Вставить httpcontext в пользовательский атрибут вне контроллера в ядре .net - PullRequest
1 голос
/ 11 июня 2019

Мне нужно ввести 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
}

Как уже упоминалось на многих сайтах, которые я посетил, например. здесь https://dotnetcoretutorials.com/2017/01/05/accessing-httpcontext-asp-net-core/ внедрение httpcontext вне контроллера может быть выполнено с помощью IHttpContextAccessor. Проблема в том, что я не знаю, как его использовать, не передавая его в конструктор. Мой пользовательский атрибут должен называться декоратором [SecondPermissionFilter(PermissionEnum.Permission, AccessLevelEnum.Create)], когда нужно передавать только настройки разрешений, поэтому нет никаких ссылок на httpcontextaccessor.

Это вообще возможно? Если нет, может быть, есть другой способ сделать это?

РЕДАКТИРОВАТЬ: Вот код SecondPermissionFilter класса:

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;
    }
}

1 Ответ

2 голосов
/ 11 июня 2019

То, что вы ищете, называется Property Injection. Согласно официальным документам это не то, что поддерживается из коробки .NET Core DI Container.

Однако вы можете использовать стороннюю библиотеку, такую ​​как Ninject или Autofac - обе они доступны через NuGet.

По моему мнению, синтаксис Ninject лучше, однако , как отмечено в этого ответа , и этот ответ само внедрение свойства считается плохой практикой. Поэтому, если возможно, я постараюсь избежать этого.

Так что вместо этого вы должны использовать один из трех методов, указанных фильтром документация , этот ответ разбивает вещи поподробнее.

Редактировать

Этот ответ конкретно касается инъекции атрибутов, второй ответ стремится достичь этого без внешних зависимостей.

...