экземпляр единого разрешения на контроллере веб-API - PullRequest
0 голосов
/ 07 февраля 2019

Есть ли способ разрешить экземпляр класса на уровне контроллера?Я хотел бы переопределить предыдущий экземпляр, созданный Unity, и назначить это новое значение через контроллер.

Проблема в том, что я не уверен, как получить доступ к контейнеру Unity в контроллере веб-приложения.

Вот мой код:

Репозиторий:

public class UserRepository: IUserRepository
{
    private UserInformation _userInfo; 
    public UserRepository(string headerValue)
    {       
        _userInfo = LoadUserData(headerValue);
    }

    public UserInformation GetUserInfo()
    {       
        return _userInfo;
    }
}

public class UserInformation
{
      public string FirstName;
      public string LastName;
}

Конфигурация Unity:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //Some code omitted
        config.DependencyResolver = new UnityDependencyResolver(UnityConfig.RegisterComponents());            
    }
}

public static class UnityConfig
{
    public static UnityContainer RegisterComponents()
    {
        //Unity Configuration
        var container = new UnityContainer();

        container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor("DummyHeaderValue"));          
        return container;
    }
}

Контроллер:

public class CustomerController : ApiController
{   
    public CustomerController()
    {
        //Something like this
        container.Resolve<UserRepository>(new InjectionConstructor(Request.GetHeader("RealHeaderValueFromHttpRequest")));
    }   
}

Тогда я должен быть в состояниииспользовать обновленный экземпляр UserRepository во всем приложении.

Есть мысли о том, как этого добиться?

Редактировать: Как указал @Nkosi, я неиметь доступ к запросу в конструкторе контроллера.Итак, позвольте мне перефразировать мой вопрос еще раз:

Как бы я инициализировал UserRepository с UserInformation объектом, который содержит информацию о текущем пользователе?Причина, по которой я хочу это сделать, заключается в том, что во всем приложении мне нужны данные пользователя и я не хочу передавать идентификатор пользователя из каждого метода

Примерно так: Из любого метода в приложении

UserInformation obj = _userRepository().GetUserInfo();

1 Ответ

0 голосов
/ 10 февраля 2019

Создание абстракции для получения доступа к запросу

public interface IHeaderService {
    string RealHeaderValueFromHttpRequest();
}

Его реализация будет иметь доступ к контексту и запрос на получение желаемой функциональности

public class HeaderService : IHeaderService {
    public string RealHeaderValueFromHttpRequest() {
        return HttpContext.Current.Request.Headers["RealHeaderValueFromHttpRequest"];
    }
}

Сервис теперь будетявно вставлено в зависимый репозиторий

public class UserRepository: IUserRepository {
    private readonly IHeaderService headerService;

    public UserRepository(IHeaderService headerService) { 
        this.headerService = headerService;
    }

    public UserInformation GetUserInfo() {
        var headerValue = headerService.RealHeaderValueFromHttpRequest();
        var _userInfo = LoadUserData(headerValue);
        return _userInfo;
    }

    //...
}

Затем репозиторий также будет явно внедрен в зависимые контроллеры.

public class CustomerController : ApiController {
    private readonly IUserRepository repositoty;

    public CustomerController(IUserRepository repositoty) {
        this.repository = repository;        
    }

    public IHttpActionResult SomeAction() {
        //NOTE: Only access user info in a controller action
        var userInfo = repository.GetUserInfo();

        //... use user info.
    }

    //...
}

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

public static class UnityConfig {
    public static UnityContainer RegisterComponents() {
        //Unity Configuration
        var container = new UnityContainer();

        container.RegisterType<IUserRepository, UserRepository>();
        container.RegisterType<IHeaderService, HeaderService>();

        return container;
    }
}
...