问题描述
|
我如何注入以下依赖项?
public class Authenticate : AuthorizeAttribute
{
[Dependency]
public IAuthenticate AuthenticateLibrary { get; set; }
[Dependency]
public ILibrary BaseLibrary { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
}
}
我正在使用Unity 2注入所有控制器。是否有针对Unity 2的教程,并将依赖项注入过滤器?
解决方法
布拉德·威尔逊(Brad Wilson)在“服务位置”上有一个很好的系列,其中包括如何创建自己的过滤器提供程序来支持依赖项注入:http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html(向下滚动到“向过滤器添加依赖项注入”部分。
复制他为UnityFilterAttributeFilterProvider.cs提供的代码。
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,attribute);
}
return attributes;
}
}
修改global.asax.cs的Application_Start,以使UnityFilterAttributeFilterProvider成为您的MVC应用程序的过滤器提供程序。
。
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);
// ...
}
使用[Dependency]属性装饰您希望Unity为其注入值的属性。然后您应该很好走。
,由于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 >();
}
...
}
,对于所有(像我一样)来到这里寻求MVC4 + Unity解决方案的人,尽管可以接受的答案很完美,但我想补充一点,现在您还可以简单地覆盖FilterAttributeFilterProvider
类的GetFilters
方法:
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;
}
}
干杯。