首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法使用Unity将依赖项注入ASP.NET Web API控制器

无法使用Unity将依赖项注入ASP.NET Web API控制器
EN

Stack Overflow用户
提问于 2012-03-02 12:29:46
回答 11查看 97.3K关注 0票数 83

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

这就是我现在正在做的。

在我的global.ascx.cs

代码语言:javascript
复制
    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;
    }

我的控制器工厂:

代码语言:javascript
复制
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);
                }
            }

它似乎从来没有在unity文件中解析依赖关系,并且我得到了一个错误,比如:

尝试创建类型为'PersonalShopper.Services.WebApi.Controllers.ShoppingListController'.的控制器时发生

错误确保控制器有一个无参数的公共构造函数。

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

控制器看起来像:

代码语言:javascript
复制
public class ShoppingListController : System.Web.Http.ApiController
    {
        private Repositories.IProductListRepository _ProductListRepository;


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

我的unity文件如下所示:

代码语言:javascript
复制
<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版本中,控制器工厂会找出需要解决的依赖项。

似乎我的控制器工厂从来没有被调用过。

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2012-03-03 14:38:28

我想通了。

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

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

创建了一个UnityHttpControllerActivator:

代码语言:javascript
复制
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);
    }
}

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

代码语言:javascript
复制
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.
       });
}
票数 43
EN

Stack Overflow用户

发布于 2012-05-15 07:45:52

这里有一个更好的解决方案,它可以正常工作。

http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver

票数 38
EN

Stack Overflow用户

发布于 2012-03-21 00:30:34

您可能想看看Unity.WebApi NuGet包,它将解决所有这些问题,并满足IDisposable组件的需求。

看见

http://nuget.org/packages/Unity.WebAPI

http://www.devtrends.co.uk/blog/introducing-the-unity.webapi-nuget-package

票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9527988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档