Dependency Injection in MVC custom filters - can't get it to work

Topics: Enterprise Library Core, General discussion
Dec 5, 2013 at 9:42 PM
Edited Dec 5, 2013 at 9:43 PM
I have a MVC 5 project (VS2013) where Unity container is set up with these Nuget packages:
  <package id="Unity" version="3.0.1304.1" targetFramework="net451" />
  <package id="Unity.AspNet.WebApi" version="3.0.1304.0" targetFramework="net451" />
  <package id="Unity.Mvc" version="3.0.1304.0" targetFramework="net451" />
So container is created and configured, all required types are registered. Like this:
container.RegisterType<IMyLogger, MyLogger>();
Now, UnityWebActivator sets FilterProvider to :
var container = UnityConfig.GetConfiguredContainer();

FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

DependencyResolver.SetResolver(new UnityDependencyResolver(container));
I suppose this should be enough for MyLogger to be injected in my custom MyExceptionHandlingAttribute where I have this property:
[Dependency]
public IMyLogger Logger { get; set; }
But Logger never gets initialized, it's always NULL.

I found a work-around:
public MyExceptionHandlingAttribute() : this(DependencyResolver.Current.GetService<IMyLogger>())
{
}

public MyExceptionHandlingAttribute(IMyLogger logger)
{
    Logger = logger;
}
So the question is why the property is not injected?
Dec 7, 2013 at 4:11 PM
Which DependencyAttribute was decorating the MyExceptionHandlingAttribute? There are two with the same name: System.Runtime.CompilerServices.DependencyAttribute or Microsoft.Practices.Unity.DependencyAttribute?

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Dec 7, 2013 at 9:11 PM
Edited Dec 7, 2013 at 9:14 PM
It's Microsoft.Practices.Unity.DependencyAttribute.

Here's the code with Dependency commented out:
using System;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using Core;
using Microsoft.Practices.Unity;

namespace Infrastructure.ExceptionHandling
{
    public class MyExceptionHandlingAttribute : HandleErrorAttribute
    {
        //[Dependency]
        public IMyLogger Logger { get; set; }

        public MyExceptionHandlingAttribute() : this(DependencyResolver.Current.GetService<IMyLogger>())
        {
        }

        public MyExceptionHandlingAttribute(IMyLogger logger)
        {
            Logger = logger;
        }

        public override void OnException(ExceptionContext filterContext)
        {
[snip]
        }
    }
}
Dec 8, 2013 at 5:54 AM
Is HandleErrorAttribute an ActionFilterAttribute?

Also, it looks like you've added both Unity bootstrapper for ASP.NET MVC and Unity bootstrapper for ASP.NET Web API. Is there a reason for that? Maybe there is a conflict there?

Everything that you've posted looks OK. A small sample application would probably help pinpoint the issue.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Dec 9, 2013 at 11:27 AM
I should have mention that this is a global filter. Anyway, here's the test project: https://cloud.mail.ru/public/31121fb94f5b/UnityGlobalFilterTest.zip
Dec 10, 2013 at 6:26 AM
The UnityFilterAttributeFilterProvider only inspects attributes so that is why the global filter does not work while the Action with the ErrorFilter attribute works.

The easiest approach would be to just perform injection when adding the Filter:
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(DependencyResolver.Current.GetService<ErrorFilter>());
        }
    }
Resolving through the container will inject the ILogger property.


~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Dec 10, 2013 at 8:17 AM
Got it. Why not add such a feature? I think it would be logical. Because now it's like in some places injection works and doesn't work in others.