I am sure that this code used to work. I have a UnityFilterProvider and a UnityGlobalFilterProvider both registered in my Unity config.
I would have expected it to pick up both IFilterProviders, but if they are both registered it will only pick up the GlobalFilterProvider. If the only one registered is the basic UnityFilterProvider then that works fine.
But I cannot get them both working together.
Am I doing something wrong? Did this used to work, but not in MVC5? Did this never work and should I do something different?
UnityFilterProvider.cs
namespace Website.Infrastructure
{
public class UnityFilterProvider : FilterAttributeFilterProvider
{
private IUnityContainer container;
public UnityFilterProvider(IUnityContainer container)
{
this.container = container;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
foreach (var filter in filters)
{
container.BuildUp(filter.Instance.GetType(), filter.Instance);
}
return filters;
}
}
}
UnityGlobalFilterProvider.cs
namespace Website.Infrastructure
{
public class UnityGlobalFilterProvider : IFilterProvider
{
private readonly IUnityContainer container;
private readonly IGlobalFilterRegistrationList filterList;
public UnityGlobalFilterProvider(IUnityContainer container, IGlobalFilterRegistrationList filterList)
{
this.container = container;
this.filterList = filterList;
}
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = new List<Filter>();
if (filterList == null || filterList.Count == 0)
return filters;
foreach (GlobalFilterRegistration registration in filterList)
{
var actionFilter = container.Resolve(registration.Type);
var filter = new Filter(actionFilter, FilterScope.Global, registration.Order);
filters.Add(filter);
}
return filters;
}
}
public class GlobalFilterRegistration
{
public GlobalFilterRegistration(Type type, int? order)
{
this.Type = type;
this.Order = order;
}
public Type Type { get; set; }
public int? Order { get; set; }
}
public class GlobalFilterRegistrationList : List<GlobalFilterRegistration>, IGlobalFilterRegistrationList
{
}
public interface IGlobalFilterRegistrationList
{
int Count { get; }
List<GlobalFilterRegistration>.Enumerator GetEnumerator();
void Add(GlobalFilterRegistration item);
}
}
UnityConfig (snip)
container.RegisterType<IFilterProvider, UnityFilterProvider>(new ContainerControlledLifetimeManager());
container.RegisterType<IFilterProvider, UnityGlobalFilterProvider>(new ContainerControlledLifetimeManager());
container.RegisterType<IGlobalFilterRegistrationList, GlobalFilterRegistrationList>(
new ContainerControlledLifetimeManager());
Anyone got any ideas?
Adding names to the provider registrations solved the problem
container.RegisterType<IFilterProvider, UnityFilterProvider>("UnityFilterProvider", new ContainerControlledLifetimeManager());
container.RegisterType<IFilterProvider, UnityGlobalFilterProvider>("UnityGlobalFilterProvider", new ContainerControlledLifetimeManager());
Adding names to the Filter registrations solved the problem.
Cheers Mike