2

我试图了解如何在 mvc 中调用控制器和操作。经过大量阅读,我发现 ExecuteCore() 方法被执行,该方法存在于 Controller.cs 类中。

protected override void ExecuteCore()
{
    // If code in this method needs to be updated, please also check the BeginExecuteCore() and
    // EndExecuteCore() methods of AsyncController to see if that code also must be updated.

    PossiblyLoadTempData();
    try
    {
        string actionName = RouteData.GetRequiredString("action");
        if (!ActionInvoker.InvokeAction(ControllerContext, actionName))
        {
            HandleUnknownAction(actionName);
        }
    }
    finally
    {
        PossiblySaveTempData();
    }
}

public IActionInvoker ActionInvoker
{
    get
    {
        if (_actionInvoker == null)
        {
            _actionInvoker = CreateActionInvoker();
        }
        return _actionInvoker;
    }
    set { _actionInvoker = value; }
}

protected virtual IActionInvoker CreateActionInvoker()
{
    // Controller supports asynchronous operations by default. 
    return Resolver.GetService<IAsyncActionInvoker>() ?? Resolver.GetService<IActionInvoker>() ?? new AsyncControllerActionInvoker();
}

当 ExecuteCore() 开始执行时,对 ActionInvoker 属性的引用会返回一个 IActionInvoker 类型。

IActionInvoker 由 AsyncControllerActionInvoker.cs 类实现,其中实现了 InvokeAction(ControllerContext, actionName) 方法。

所以我的问题是:

  1. IActionInvoker 接口如何在这里实例化,并由 ActionInvoker 属性返回?
  2. 对属性的引用是否返回 AsyncControllerActionInvoker 类的对象,以便我们可以使用该对象来调用 InvokeAction(ControllerContext, actionName) 方法。
  3. 做什么Resolver.GetService<IAsyncActionInvoker>()Resolver.GetService<IActionInvoker>()做什么?

请帮助我理解这一点。

4

1 回答 1

1

ASP.NET 有一种内置的依赖注入。

这意味着控制器没有对特定类的硬引用,而是对接口的引用。然后Resolver将其配置为在请求实例时返回特定类型。例如(示例代码,我不知道确切的方法名)

Resolver.Bind<IActionInvoker>().To<ActionInvoker>();   // if an IActionInvoker is requested, return an instance of type ActionInvoker.

在此配置之后,调用GetService将为您提供一个实例ActionInvoker

所以,回答你的问题:

  1. IActionInvoker 接口如何在这里实例化,并由 ActionInvoker 属性返回?

通过预先配置解析器,解析器知道要创建和返回哪种类型

  1. 对属性的引用是否返回 AsyncControllerActionInvoker 类的对象,以便我们可以使用该对象来调用 InvokeAction(ControllerContext, actionName) 方法。

是和不是。是的,该属性将确保您拥有一个IActionInvoker 可以用来调用的实现对象InvokeAction。不,您不能保证它是类型IAsyncActionInvoker(取决于解析器的配置)

  1. Resolver.GetService() 和 Resolver.GetService() 做什么?

他们要求解析器实例化一个实现给定接口的对象。解析器将在其配置中查找接口,实例化适当的对象并将其返回给调用者。

依赖注入是一种解耦代码的方法。由于您只引用接口,因此您没有硬依赖,您只需重新配置 DI 容器(Resolver在这种情况下),您将使用另一个类,而您的客户端类不知道它。

于 2013-05-08T17:59:57.243 回答