Pat*_*ick 11 dependency-injection unity-container filter asp.net-mvc-3 asp.net-mvc-4
我怎么能注入以下依赖?
public class Authenticate : AuthorizeAttribute
{
[Dependency]
public IAuthenticate AuthenticateLibrary { get; set; }
[Dependency]
public ILibrary BaseLibrary { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我使用Unity 2注入所有控制器.是否有Unity 2的教程并将依赖项注入过滤器?
Joh*_*ers 13
Brad Wilson有一个很好的服务定位系列,其中包括如何创建自己的过滤器提供程序,可以支持依赖注入:http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html(向下滚动到"向筛选器添加依赖关系注入"部分.
UnitFilterAttributeFilterProvider.cs
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider {
private IUnityContainer _container;
public UnityFilterAttributeFilterProvider(IUnityContainer container) {
_container = container;
}
protected override IEnumerable<FilterAttribute> GetControllerAttributes(
ControllerContext controllerContext,
ActionDescriptor actionDescriptor) {
var attributes = base.GetControllerAttributes(controllerContext,
actionDescriptor);
foreach (var attribute in attributes) {
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
protected override IEnumerable<FilterAttribute> GetActionAttributes(
ControllerContext controllerContext,
ActionDescriptor actionDescriptor) {
var attributes = base.GetActionAttributes(controllerContext,
actionDescriptor);
foreach (var attribute in attributes) {
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
}
Run Code Online (Sandbox Code Playgroud)
.
protected void Application_Start() {
// ...
var oldProvider = FilterProviders.Providers.Single(
f => f is FilterAttributeFilterProvider
);
FilterProviders.Providers.Remove(oldProvider);
var container = new UnityContainer();
var provider = new UnityFilterAttributeFilterProvider(container);
FilterProviders.Providers.Add(provider);
// ...
}
Run Code Online (Sandbox Code Playgroud)
由于Unity没有实例化过滤器,因此无法注入它们.您将不得不求助于服务定位器模式,如下所示:
public class Authenticate : AuthorizeAttribute
{
public IAuthenticate AuthenticateLibrary { get; private set; }
public ILibrary BaseLibrary { get; private set; }
public Authenticate()
{
AuthenticateLibrary = DependencyResolver.Current.GetService<IAuthenticate>();
BaseLibrary = DependencyResolver.Current.GetService<ILibrary >();
}
...
}
Run Code Online (Sandbox Code Playgroud)
对于那些(像我一样)来到这里寻找MVC4 + Unity解决方案的人来说,虽然接受的答案完美无缺,但我想补充说现在你也可以简单地覆盖类的GetFilters方法FilterAttributeFilterProvider:
public class CustomFilterProvider : FilterAttributeFilterProvider
{
private readonly IUnityContainer container;
public CustomFilterProvider(IUnityContainer container)
{
this.container = container;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
var enumerable = filters as IList<Filter> ?? filters.ToList();
foreach (var filter in enumerable)
{
container.BuildUp(filter.Instance.GetType(), filter.Instance);
}
return enumerable;
}
}
Run Code Online (Sandbox Code Playgroud)
干杯.