В качестве общего решения (без какой-либо специальной поддержки интеграции вашей структуры DI), MVC3 запрашивает IDependencyResolver
для IFilterProvider
.Другими словами, хитрость заключается в следующем:
- Удалите
FilterAttributeFilterProvider
из коллекции System.Web.Mvc.FilterProviders
. - Зарегистрируйте
IDependencyResolver
для вашей конкретной структуры DI (если вы 'это еще не сделано). - Зарегистрируйте пользовательский
IFilterProvider
в своем контейнере, который может внедрить свойства любого запрошенного атрибута.
Это выглядит так:
var container = new [your favorite container];
// 1. Remove the FilterAttributeFilterProvider from the collection.
var providers = FilterProviders.Providers
.OfType<FilterAttributeFilterProvider>().ToList();
providers.ForEach(p => FilterProviders.Providers.Remove(p));
// 2. Register a IDependencyResolver
DependencyResolver.SetResolver(new YourDiResolver(container));
// 3. Register a customer IFilterProvider.
container.Register<IFilterProvider, YourAttributeFilterProvider>();
YourAttributeFilterProvider
будет выглядеть следующим образом:
private class YourAttributeFilterProvider
: FilterAttributeFilterProvider
{
private readonly [your favorite container] container;
public YourAttributeFilterProvider(
[your favorite container] container)
: base(false)
{
this.container = container;
}
public override IEnumerable<Filter> GetFilters(
ControllerContext controllerContext,
ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext,
actionDescriptor).ToList();
// Inject properties into attribute here.
filters.ForEach(f => container.InjectProperties(f.Instance));
return filters;
}
}
Многие фреймворки, такие как Ninject и Autofac, имеют встроенную поддержку для этого через свои пакеты интеграции MVC.Тем не менее, важно понять, как сделать это вручную.
ПРЕДУПРЕЖДЕНИЕ:
Одно большое предупреждение о внедрении зависимостей в атрибуты фильтра MVC. MVC кэширует атрибуты и повторно использует экземпляры в течение срока действия домена приложения.Это означает, что они практически становятся синглетонами и увлекают за собой свои зависимости.Другими словами: эти зависимости также станут синглетонами, что также известно как проблема зависимостей в неволе .Поэтому убедитесь, что вы только внедряете синглеты в свои атрибуты, потому что ваша производственная система будет обеспокоена ошибками параллелизма, если вы этого не сделаете.
Хотя большинство платформ DI поддерживают внедрение в атрибуты фильтров, ни одна из платформ не помогает в устранении этой проблемы.Так что лучшим решением будет сохранить ваши атрибуты пассивными, как объяснено здесь и здесь .