Mvc 3/Unity 2 внедрить зависимости в фильтр?
Как я могу ввести следующие зависимости??
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 и внедрению зависимостей в фильтры?
3 ответа
Брэд Уилсон (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,
actionDescriptor);
foreach (var attribute in attributes) {
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
}
- Измените Application_Start файла global.asax.cs, чтобы сделать 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);
// ...
}
- Украсьте свойства, для которых вы хотите, чтобы Unity ввел значение, с помощью атрибута [Dependency]. И тогда тебе должно быть хорошо идти.
Поскольку 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, хотя принятые ответы работают отлично, я хотел добавить, что теперь вы также можете просто переопределить 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;
}
}
Приветствия.