无法使用 Unity 将依赖项注入 ASP.NET Web API 控制器 [英] Cannot Inject Dependencies into ASP.NET Web API Controller using Unity

查看:25
本文介绍了无法使用 Unity 将依赖项注入 ASP.NET Web API 控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人成功地使用 IoC 容器将依赖项注入 ASP.NET WebAPI 控制器?我似乎无法让它工作.

Has anyone had any success running using an IoC container to inject dependencies into ASP.NET WebAPI controllers? I cannot seem to get it to work.

这就是我现在正在做的事情.

This is what I'm doing now.

在我的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;
    }

我的控制器工厂:

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);
                }
            }

它似乎从不查看我的统一文件来解决依赖关系,我收到如下错误:

It never seems to look in my unity file to resolve dependencies, and I get an error like:

尝试创建类型的控制器时发生错误'PersonalShopper.Services.WebApi.Controllers.ShoppingListController'.确保控制器具有无参数的公共构造函数.

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.

在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext控制器上下文,类型控制器类型)在 System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContextcontrollerContext, HttpControllerDescriptor controllerDescriptor)在 System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext控制器上下文,字符串控制器名称)在 System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage请求,CancellationToken 取消令牌)在 System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage请求,CancellationToken 取消令牌)

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)

控制器看起来像:

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


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

我的统一文件看起来像:

My unity file looks like:

<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>

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

Note that I don't have a registration for the controller itself because in previous versions of mvc the controller factory would figure out that the dependencies needed to be resolved.

似乎我的控制器工厂从未被调用过.

It seems like my controller factory is never being called.

推荐答案

想通了.

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

For ApiControllers, MVC 4 uses a System.Web.Http.Dispatcher.IHttpControllerFactory and System.Web.Http.Dispatcher.IHttpControllerActivator to create the controllers. If there is no static method to register what the implementation of these they are; when they are resolved, the mvc framework looks for the implementations in the dependency resolver, and if they are not found, uses the default implementations.

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

I got unity resolution of controller dependencies working by doing the following:

创建一个 UnityHttpControllerActivator:

Created a 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);
    }
}

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

Registered that controller activator as the implementation in the unity container itself:

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.
       });
}

这篇关于无法使用 Unity 将依赖项注入 ASP.NET Web API 控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆