Search code examples
c#asp.net-coredependency-injection

Dependency Injection in IAuthorizationFilter ASP.Net Core 3


I create a filter IAuthorizationFilter and I need to use DepencyInjection in this attribute.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AllowAccessAttribute : Attribute, IAuthorizationFilter
{
    private readonly IDomainUnitOfWork unitofwork;
    private readonly HttpContext httpContext;

    public AllowAccessAttribute(IDomainUnitOfWork unitofwork,HttpContext httpContext)
    {
        this.unitofwork = unitofwork;
        this.httpContext = httpContext;
    }
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        string controller = context.RouteData.Values["controller"].ToString();
        string action = context.RouteData.Values["action"].ToString();
        var userId = httpContext.User.Identity.GetUserId<long>();
        var access = string.Format("{0}:{1}", controller, action);
        if (unitofwork.UserRepository.AccessLevelRepository.ValidateAccess(userId, access))
            context.Result = new StatusCodeResult(403);
    }
}

When I need to use the this Attribute it show me error

[HttpGet]
[AllowAccess]
public async Task<ApiReturn> ChangeUserActiveStatus(long id)
{
    var result = await dispatchers.SendAsync(new UserActiveStateCommand { id = id });
    if (result.Success)
    {
        return Ok();
    }
    return BadRequest(result.Exception);
}

And show this error:

There is no argument given that corresponds to the required formal parameter 'unitofwork' of 'AllowAccessAttribute.AllowAccessAttribute(IDomainUnitOfWork, HttpContext)

What's the problem? how can I solve this problem?


Solution

  • You need to register the service in IoC container.

    Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddScoped<IDomainUnitOfWork, DomainUnitOfWork>(); // per request injection
        ...
    }
    

    Try also changing the attribute of the method to TypeFilter:

    [HttpGet]
    [TypeFilter(typeof(AllowAccessAttribute))]
    public async Task<ApiReturn> ChangeUserActiveStatus(long id)