c# - 无法使用 Unity 将依赖项注入(inject) ASP.NET Web API Controller

标签 c# .net asp.net-web-api unity-container

有没有人成功使用 IoC 容器将依赖项注入(inject) ASP.NET WebAPI Controller ?我似乎无法让它工作。

这就是我现在正在做的。

在我的 global.ascx.cs 中:

    public static void RegisterRoutes(RouteCollection routes)
    {
            // code intentionally omitted 
    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        IUnityContainer container = BuildUnityContainer();

        System.Web.Http.GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
            t =>
            {
                try
                {
                    return container.Resolve(t);
                }
                catch (ResolutionFailedException)
                {
                    return null;
                }
            },
            t =>
            {
                try
                {
                    return container.ResolveAll(t);
                }
                catch (ResolutionFailedException)
                {
                    return new System.Collections.Generic.List<object>();
                }
            });

        System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container)); 

        BundleTable.Bundles.RegisterTemplateBundles();
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer().LoadConfiguration();

        return container;
    }

我的 Controller 工厂:

public class UnityControllerFactory : DefaultControllerFactory
            {
                private IUnityContainer _container;

                public UnityControllerFactory(IUnityContainer container)
                {
                    _container = container;
                }

                public override IController CreateController(System.Web.Routing.RequestContext requestContext,
                                                    string controllerName)
                {
                    Type controllerType = base.GetControllerType(requestContext, controllerName);

                    return (IController)_container.Resolve(controllerType);
                }
            }

它似乎从来没有在我的统一文件中查找来解决依赖关系,我收到如下错误:

An error occurred when trying to create a controller of type 'PersonalShopper.Services.WebApi.Controllers.ShoppingListController'. Make sure that the controller has a parameterless public constructor.

at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext controllerContext, Type controllerType) at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext controllerContext, HttpControllerDescriptor controllerDescriptor) at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext controllerContext, String controllerName) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

Controller 看起来像:

public class ShoppingListController : System.Web.Http.ApiController
    {
        private Repositories.IProductListRepository _ProductListRepository;


        public ShoppingListController(Repositories.IUserRepository userRepository,
            Repositories.IProductListRepository productListRepository)
        {
            _ProductListRepository = productListRepository;
        }
}

我的统一文件看起来像:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <container>
    <register type="PersonalShopper.Repositories.IProductListRepository, PersonalShopper.Repositories" mapTo="PersonalShopper.Implementations.MongoRepositories.ProductListRepository, PersonalShopper.Implementations" />
  </container>
</unity>

请注意,我没有注册 Controller 本身,因为在以前版本的 mvc 中, Controller 工厂会发现需要解决依赖关系。

似乎我的 Controller 工厂从未被调用过。

最佳答案

想通了。

对于 ApiControllers,MVC 4 使用 System.Web.Http.Dispatcher.IHttpControllerFactorySystem.Web.Http.Dispatcher.IHttpControllerActivator创建 Controller 。如果没有静态方法来注册它们是什么实现;当它们被解析时,mvc 框架在依赖解析器中寻找实现,如果没有找到,则使用默认实现。

我通过执行以下操作获得了 Controller 依赖项的统一解析:

创建了一个 UnityHttpControllerActivator:

public class UnityHttpControllerActivator : IHttpControllerActivator
{
    private IUnityContainer _container;

    public UnityHttpControllerActivator(IUnityContainer container)
    {
        _container = container;
    }

    public IHttpController Create(HttpControllerContext controllerContext, Type controllerType)
    {
        return (IHttpController)_container.Resolve(controllerType);
    }
}

将该 Controller 激活器注册为统一容器本身中的实现:

protected void Application_Start()
{
    // code intentionally omitted

    IUnityContainer container = BuildUnityContainer();
    container.RegisterInstance<IHttpControllerActivator>(new UnityHttpControllerActivator(container));

    ServiceResolver.SetResolver(t =>
       {
         // rest of code is the same as in question above, and is omitted.
       });
}

关于c# - 无法使用 Unity 将依赖项注入(inject) ASP.NET Web API Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9527988/

相关文章:

c# - 将 Azure SQL 数据库连接到 ASP.NET 项目

c# - 获取 Outlook 2010 规则说明

c# - 没有 MediaTypeFormatter 可用于读取 asp.net web api 中类型为 'Advertisement' 的对象

c# - 刷新DataGridView?

c# - 修改了 Entity Framework 集合;枚举操作可能无法执行

c# - 未优化的 IEnumerable<>.Last with predicate

c# - 如何使用 Entity Framework 生成和自动递增 Id

c# - 使用tcp将 float 组从c++发送到c#

带有刷新 token 的 ASP.NET 个人帐户

c# - .NET Core 2.1 Web API 是否支持基于约定的路由?