#c# #inversion-of-control #identity
Вопрос:
Когда мой контроллер использует объект, который принимает идентификатор в качестве входных данных, я, конечно, мог бы сделать это:
public class MyController : ControllerBase { private readonly MyRepository _repository; public MyController() { _repository = new MyRepository(HttpContext.User.Identity); } }
Однако ручное создание репозитория (или любого другого объекта, который нуждается в идентификации) не очень изящно. Лучшим способом было бы использовать контейнер IOC для введения идентификатора
Есть ли способ добавить идентификатор в контейнер IOC, чтобы я мог просто сделать это:
public class MyController : ControllerBase { private readonly MyRepository _repository; public MyController(MyRepository repository) { _repository = repository; } }
Идентичность, конечно, полезна во всех видах объектов. Его можно использовать в репозитории БД для добавления метаданных, таких как обновление пользователя. Или он может быть использован объектом, обращающимся к другой службе для олицетворения
Комментарии:
1. У вас может быть интерфейс IIdentityProvider в качестве зависимости от репозитория. У него должен быть метод или свойство для возврата идентификатора. И реализующий класс должен получить доступ к идентификатору из HttpContext и вернуться в реализующем свойстве или методе.
2. Но тогда должен ли конструктор IdentityProvider иметь HttpContext в качестве параметра в конструкторе ? Тогда мне нужно было бы зарегистрировать HttpContext в контейнере. Разве это не та же самая проблема ?
3. В этом нет необходимости… Ваш класс должен иметь прямой доступ
HttpContext.User.Identity
. класс будет просто оболочкойHttpContext.User.Identity
и не будет зависеть от HttpContext.
Ответ №1:
Вдохновленный предложением @Chetan, но немного по-другому, это сработало для меня. Я добавил эти регистрации в свой стартап:
services.AddHttpContextAccessor(); services.AddScopedlt;IIdentityProvider, IdentityProvidergt;();
Первая строка сделает IHttpContextAccessor доступным для инъекции. Затем я могу построить свою личность, как это:
internal class IdentityProvider : IIdentityProvider { public IdentityProvider(IHttpContextAccessor contextAccessor) { Identity = contextAccessor.HttpContext?.User.Identity; } public IIdentity Identity { get; } }
Затем IIdentityProvider будет доступен для MyRepository и других объектов, где это необходимо
public class MyRepository { private readonly IIdentity _identity; public MyRepository(IIdentityProvider identityProvider) { _identity = identityProvider.Identity; } }