将 httpcontext 注入 .net 核心中控制器外部的自定义属性

Inject httpcontext into custom attribute outside controller in .net core

我需要将 httpcontext 注入到控制器外部使用的自定义属性中。我找到了几种解决方案如何在控制器中执行此操作,但我的情况有点棘手。现在我的 PermissionController

中有以下代码
[PermissionFilter(PermissionEnum.Permission, AccessLevelEnum.Create)] <-- it works perfectly
[HttpPost("users/{userId}")]
public async Task<IActionResult> 
  AssignPermissionToUser([FromBody] List<PermissionToVM> permissions, int userId)
{
    await _permissionService.Assign(permissions); <-- .Assign() extension
    //code goes here
}

上面的方法中调用了扩展方法.Assign。此方法代码在下面可用。

//[SecondPermissionFilter(PermissionEnum.Permission,
   AccessLevelEnum.Create)] <-- here I check permissions but don't 
   know how to inject the httpcontext
public async Task Assign(List<PermissionToVM> permissions)
{
    //code goes here
}

正如我访问过的许多网站所述f.e。这里 https://dotnetcoretutorials.com/2017/01/05/accessing-httpcontext-asp-net-core/ 可以使用 IHttpContextAccessor 在控制器外部注入 httpcontext。问题是我不知道如何在不将它传递给构造函数的情况下使用它。当只传递权限设置时,我的自定义属性应该被称为装饰器 [SecondPermissionFilter(PermissionEnum.Permission, AccessLevelEnum.Create)],因此没有任何对 httpcontextaccessor 的引用。

这可能吗?如果没有,也许还有另一种方法可以做到这一点?

编辑:这是 SecondPermissionFilter class 的代码:

public sealed class SecondPermissionFilterAttribute : Attribute
{
    private readonly PermissionEnum _requestedPermission;
    private readonly IEnumerable<AccessLevelEnum> _accessLevelCollection;
    private readonly IHttpContextAccessor _contextAccessor; //<-- how to inject?

    public PermissionFilterAttribute(PermissionEnum requestedPermission, params AccessLevelEnum[] accessLevelCollection)
    {
        _requestedPermission = requestedPermission;
        _accessLevelCollection = accessLevelCollection;
    }
}

你要找的是一个叫做Property Injection的东西。根据 official docs 这不是 .NET Core DI 容器开箱即用的支持。

但是您可以使用第三方库,例如 Ninject or Autofac - 两者都可以通过 NuGet 获得。

在我看来 Ninject 语法更好,然而 , and 属性 中所述,注入本身被认为是不好的做法。所以如果可能的话我会尽量避免它。

所以您应该改用过滤器指定的三种方法之一 documentation, 可以进一步分解。

编辑

This answer deals specificically with Attribute injection, the second answer 看起来无需外部依赖即可实现此目的。