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

有没有人有任何成功运行使用IoC容器注入到ASP.NET WebAPI控制器的依赖? 我似乎无法得到它的工作。

这就是我现在正在做的。

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

它似乎从来没有看我的统一文件来解决依赖,我得到一个错误,如:

尝试创buildtypes为“PersonalShopper.Services.WebApi.Controllers.ShoppingListController”的控制器时发生错误。 确保控制器有一个无参数的公共构造函数。

在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext controllerContext,typescontrollerType)在System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext controllerContext,HttpControllerDescriptor controllerDescriptor)在System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController (HttpControllerContext controllerContext,string控制器名称)在System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage请求,CancellationToken的cancellationToken)System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage请求,CancellationToken的cancellationToken)

控制器看起来像:

 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> 

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

看来我的控制器工厂从来没有被称为。

弄清楚了。

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

我通过执行以下操作来实现控制器依赖关系的统一parsing:

创build一个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); } } 

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

 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.WebApi NuGet包,它将把所有这些都sorting出来,并且还会处理IDisposable组件。

看到

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

要么

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

微软已经为此创build了一个包。

从包pipe理器控制台运行以下命令。

安装包Unity.AspNet.WebApi

如果你已经安装了Unity,它会询问你是否要覆盖App_Start \ UnityConfig.cs。 答复否,然后继续。

没有必要改变任何其他代码和DI(与统一)将工作。

我有同样的错误,并正在寻找互联网解决scheme几个小时。 最终,在我调用WebApiConfig.Register之前,我必须注册Unity。 我的global.asax现在看起来像

 public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { UnityConfig.RegisterComponents(); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } 

对我来说,这解决了Unity无法解决我的控制器中的依赖问题

在最近的RC中,我发现不再有SetResolver方法。 为了启用IoC for controller和webapi,我使用了Unity.WebApi(NuGet)和下面的代码:

 public static class Bootstrapper { public static void Initialise() { var container = BuildUnityContainer(); GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new ControllerActivator())); } private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.Configure(c => c.Scan(scan => { scan.AssembliesInBaseDirectory(); scan.With<UnityConfiguration.FirstInterfaceConvention>().IgnoreInterfacesOnBaseTypes(); })); return container; } } public class ControllerActivator : IControllerActivator { IController IControllerActivator.Create(RequestContext requestContext, Type controllerType) { return GlobalConfiguration.Configuration.DependencyResolver.GetService(controllerType) as IController; } } 

我也使用UnityConfiguration(也来自NuGet)来实现IoC魔术。 ;)

在阅读完答案之后,我仍然需要做大量的工作以便在这个问题上下功夫,所以这里是为了同行的利益:在ASP.NET 4 Web API RC中这是你需要做的(8月8日'13):

  1. 添加对“Microsoft.Practices.Unity.dll”的引用[我在版本3.0.0.0,通过NuGet添加]
  2. 添加对“Unity.WebApi.dll”的引用[我在版本0.10.0.0,通过NuGet添加]
  3. 在容器中注册types映射 – 类似于通过Unity.WebApi项目添加到项目中的Bootstrapper.cs中的代码。
  4. 在从ApiController类inheritance的控制器中,创build具有作为映射types的参数types的参数化构造函数

瞧,你会得到注入你的构造函数没有另一行代码的依赖关系!

注意:我从本文的作者的评论中获得了这些信息。

我有同样的exception被抛出,在我的情况下,我有一个MVC3和MVC4二进制文件之间的冲突。 这阻止了我的控制器在我的IOC容器中正确注册。 检查你的web.config,并确保它指向正确的MVC版本。

由于注册与Unity的控制器发生此问题。 我通过按照惯例使用注册来解决这个问题,如下所示。 请根据需要筛选出其他types。

  IUnityContainer container = new UnityContainer(); // Do not register ApiControllers with Unity. List<Type> typesOtherThanApiControllers = AllClasses.FromLoadedAssemblies() .Where(type => (null != type.BaseType) && (type.BaseType != typeof (ApiController))).ToList(); container.RegisterTypes( typesOtherThanApiControllers, WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.ContainerControlled); 

上面的例子也使用AllClasses.FromLoadedAssemblies() 。 如果您正在从基本path加载程序集,则可能无法按预期在使用Unity的Web API项目中正常工作。 请看看我对这个问题的回答。 https://stackoverflow.com/a/26624602/1350747

使用Unity.WebAPI NuGet包时遇到同样的问题。 问题是该包从未在我的Global.asax中添加对UnityConfig.RegisterComponents()的调用。

Global.asax.cs应该如下所示:

 public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { UnityConfig.RegisterComponents(); ... } } 

ASP.NET Web API 2的简短摘要

从NuGet安装Unity

创build一个名为UnityResolver的新类:

 using Microsoft.Practices.Unity; using System; using System.Collections.Generic; using System.Web.Http.Dependencies; public class UnityResolver : IDependencyResolver { protected IUnityContainer container; public UnityResolver(IUnityContainer container) { if (container == null) { throw new ArgumentNullException("container"); } this.container = container; } public object GetService(Type serviceType) { try { return container.Resolve(serviceType); } catch (ResolutionFailedException) { return null; } } public IEnumerable<object> GetServices(Type serviceType) { try { return container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List<object>(); } } public IDependencyScope BeginScope() { var child = container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { container.Dispose(); } } 

创build一个名为UnityConfig的新类:

 public static class UnityConfig { public static void ConfigureUnity(HttpConfiguration config) { var container = new UnityContainer(); container.RegisterType<ISomethingRepository, SomethingRepository>(); config.DependencyResolver = new UnityResolver(container); } } 

编辑App_Start – > WebApiConfig.cs

 public static void Register(HttpConfiguration config) { UnityConfig.ConfigureUnity(config); ... 

现在它会工作。

原始来源,但有点修改: https : //docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection