I searched a long time for a solution for my problem. I have a custom AuthorizeAttribute that needs a Dependency to a "Service" that has access to a DbContext. Sadly the Dependency Injection did not work in the custom AuthorizeAttribute and was always null.
I came up with an (for me) acceptable solution. Now I want to know if my solution can cause unforeseen behaviour?
Global.asax.cs
CustomAuthorizeAttribute.AuthorizeServiceFactory = () => unityContainer.Resolve<AuthorizeService>();
CustomAuthorizeAttribute.cs
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public static Func<AuthorizeService> AuthorizeServiceFactory { get; set; }
public Privilege Privilege { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
return AuthorizeServiceFactory().AuthorizeCore(httpContext, Privilege);
}
}
AuthorizeService.cs
public class AuthorizeService
{
[Dependency]
public UserService UserService { private get; set; }
public bool AuthorizeCore(HttpContextBase httpContext, Privilege privilege)
{
ApplicationUser user = UserService.FindByName(httpContext.User.Identity.Name);
return UserService.UserHasPrivilege(user.Id, privilege.ToString());
}
}
Is this an acceptable solution? Will I run into nasty problems in the future or is there maybe a better way to use Dependency Injection in a custom AuthorizeAttribute?
You can also try this:
ASP.NET Web API and dependencies in request scope
In ASP.NET Core you can request services easily as below:
An implementation of
IControllerFactory
in theSystem.Web.Mvc
namespace creates instances your Controllers for web requests. The Controller Factory usesSystem.Web.Mvc.DependencyResolver
to resolve dependencies in each controller.However, ActionFilters/Attributes in the MVC pipeline are not created from the Controller Factory so dependencies are not resolved using
System.Web.Mvc.DependencyResolver
. This is why your dependency was alwaysnull
.Now,
System.Web.Mvc.DependencyResolver
ispublic
andstatic
so you can access it yourself.Assuming your
UserService
has a dependency scope of WebRequest, i.e. its lifetime is One Per web request and tied to the lifetime ofHttpContext
of a web request this will not construct a newUserService
if one has been resolved previously or after if this is the first timeUserService
has been resolved for the given web request.