1

I'm working on an ASP.NET web application that uses Web API 2 and Unity. We've decorated our controllers/controller methods with a subclass of the built-in System.Web.Http.AuthorizeAttribute to apply authorization for our various REST endpoints exposed by Web API.

We would like to be able to inject dependencies into this attribute using Unity. I've done quite a bit of searching, but most examples are just different enough from my use case to not be useful.

How do I go about injecting dependencies into my System.Web.Http.AuthorizeAttribute subclass using Unity?

I've tried creating a custom FilterProvider that calls Unity's BuildUp method on the attribute instance, but I'm not sure which base class I should be extending or interface I should be implementing.

Nathan Friend
  • 12,155
  • 10
  • 75
  • 125
  • 2
    Don't inject behaviour into attributes: http://stackoverflow.com/a/7194467/126014 – Mark Seemann Oct 27 '15 at 16:57
  • I think the below approach doesn't suffer from the same pitfalls you described above as the injections are also driven by attributes, and can be wholly populated if one was to instantiate the attribute directly before using. – NStuke Sep 27 '16 at 23:20

1 Answers1

3

You have to implement IFilterProvider. If you extend ActionDescriptorFilterProvider you can call base.GetFilters to get the filters specified both at a controller and action level.

public class UnityFilterProvider : ActionDescriptorFilterProvider, IFilterProvider
{
    private readonly IUnityContainer _container;

    public UnityFilterProvider(IUnityContainer container)
    {
        _container = container;
    }

    public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
    {
        var attributes = base.GetFilters(configuration, actionDescriptor).ToList();

        foreach (var attr in attributes)
        {
            _container.BuildUp(attr.Instance.GetType(), attr.Instance);
        }
        return attributes;
    }
}

You have to register it into the infrastructure so it is used instead of the default one:

//Register the filter injector
var providers = config.Services.GetFilterProviders().ToList();
var defaultprovider = providers.Single(i => i is ActionDescriptorFilterProvider);
config.Services.Remove(typeof(IFilterProvider), defaultprovider);
config.Services.Add(typeof(IFilterProvider), new UnityFilterProvider(UnityConfig.Container));
Nathan Friend
  • 12,155
  • 10
  • 75
  • 125
Francesc Castells
  • 2,692
  • 21
  • 25