不能把依赖注入使用Unity的ASP.NET Web API控制器 [英] Cannot Inject Dependencies into ASP.NET Web API Controller using Unity

查看:903
本文介绍了不能把依赖注入使用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.

这是我在做什么了。

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

我的控制器工厂:

My controller factory:

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   controllerContext,类型controllerType)        在System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext   controllerContext,HttpControllerDescriptor controllerDescriptor)        在System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext   controllerContext,串controllerName)        在System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(Htt的prequestMessage   请求的CancellationToken的CancellationToken)        在System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(Htt的prequestMessage   请求的CancellationToken的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>

请注意,我没有对控制器本身的注册,因为在$ P $ MVC控制器工厂pvious的版本会找出所需的依赖得到解决。

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.IHttpControllerFactory System.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天全站免登陆