Injecting dependencies into custom Web API action filter attribute with Autofac

Mohammad Sepahvand picture Mohammad Sepahvand · Apr 25, 2014 · Viewed 18.5k times · Source

I'm trying to resolve the dependencies of my custom AuthorizeAttribute which I use to decorate my API controllers in an MVC4 app. Problem is that I keep getting a NullReferenceException on the service dependency I use within my custom filter. Here is my Autofac configuration:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var builder = new ContainerBuilder();
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerApiRequest();
        builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerApiRequest();
        builder.RegisterAssemblyTypes(typeof(UserProfileRepository).Assembly)
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces().InstancePerApiRequest();

        builder.RegisterAssemblyTypes(typeof(IUserProfileMapper).Assembly)
            .Where(t => t.Name.EndsWith("Mapper"))
            .AsImplementedInterfaces().InstancePerApiRequest();

        builder.RegisterAssemblyTypes(typeof(UserProfileSvc).Assembly)
            .Where(t => t.Name.EndsWith("Svc"))
            .AsImplementedInterfaces().InstancePerApiRequest();

        builder.RegisterWebApiFilterProvider(config);
        var container = builder.Build();
        var resolver = new AutofacWebApiDependencyResolver(container);
        config.DependencyResolver = resolver;
    }
}

and my custom authorize filter:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    public IAuthenticationSvc _authenticationSvc;
    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (!base.IsAuthorized(actionContext))
        {
            return false;
        }
        var trueUserId = WebSecurity.CurrentUserId;

        if (_authenticationSvc.GetUsersRoles(trueUserId).Any(x => x == "Admin")) return true;
        // NullReferenceException on _authenticationSvc
     }
}

According to the official docs all that is needed is:

var builder = new ContainerBuilder();
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

But that doesn't seem to do the trick either. Appreciate any help.

Answer

Toan Nguyen picture Toan Nguyen · Apr 29, 2014

You should configure property injection for your attribute

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    public IAuthenticationSvc AuthenticationSvc { get; set; }
}

and the builder

builder.RegisterType<MyAuthorizeAttribute>().PropertiesAutowired();