Ove*_*d D 81 .net c# unity-container 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;
}
Run Code Online (Sandbox Code Playgroud)
我的控制器工厂:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎永远不会在我的统一文件中查找解决依赖关系,我得到一个错误,如:
尝试创建"PersonalShopper.Services.WebApi.Controllers.ShoppingListController"类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.
在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(HttpRequestMessage请求,的CancellationToken的CancellationToken)在System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage请求,的CancellationToken的CancellationToken)
控制器看起来像:
public class ShoppingListController : System.Web.Http.ApiController
{
private Repositories.IProductListRepository _ProductListRepository;
public ShoppingListController(Repositories.IUserRepository userRepository,
Repositories.IProductListRepository productListRepository)
{
_ProductListRepository = productListRepository;
}
}
Run Code Online (Sandbox Code Playgroud)
我的统一文件看起来像:
<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>
Run Code Online (Sandbox Code Playgroud)
请注意,我没有控制器本身的注册,因为在以前的mvc版本中,控制器工厂会发现需要解决依赖关系.
好像我的控制器工厂从未被调用过.
Ove*_*d D 42
弄清楚了.
对于ApiControllers,MVC 4使用System.Web.Http.Dispatcher.IHttpControllerFactory和System.Web.Http.Dispatcher.IHttpControllerActivator来创建控制器.如果没有静态方法来注册它们的实现是什么; 当它们被解析时,mvc框架在依赖项解析器中查找实现,如果找不到它们,则使用默认实现.
通过执行以下操作,我获得了控制器依赖项的统一解析:
创建了一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
注册控制器激活器作为统一容器本身的实现:
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.
});
}
Run Code Online (Sandbox Code Playgroud)
小智 37
有一个更好的解决方案在这里正常工作
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
Pau*_*les 22
您可能需要查看Unity.WebApi NuGet包,它将对所有这些进行排序,并且还可以满足IDisposable组件的需要.
看到
http://nuget.org/packages/Unity.WebAPI
要么
http://www.devtrends.co.uk/blog/introducing-the-unity.webapi-nuget-package
微软已经为此创建了一个包.
从包管理器控制台运行以下命令.
安装包Unity.AspNet.WebApi
如果您已经安装了Unity,它将询问您是否要覆盖App_Start\UnityConfig.cs.回答否并继续.
无需更改任何其他代码,DI(带统一)将起作用.