Простой инжектор: как ввести HttpContext?

Я начал использовать простой инжектор в качестве контейнера DI (в основном по причине производительности: если у кого-то есть предложения, пожалуйста, дайте мне знать), но некоторые из классов, которые я написал, используют HttpContextBase в качестве параметра конструктора. Я решил пока удалить его из конструктора и создать свойство, что-то вроде этого:

    public HttpContextBase HttpContext
    {
        get
        {
            if (null == _httpContext)
                _httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
            return _httpContext;
        }
        set
        {
            _httpContext = value;
        }
    }

но мне не нравится это решение... какие-нибудь советы?

1 ответов


вы всегда должны отдавать предпочтение инъекции конструктора над чем-либо еще. Это почти всегда возможно. Вы можете зарегистрировать свой HttpContextBase следующим образом:

container.Register<HttpContextBase>(() =>
    new HttpContextWrapper(HttpContext.Current), 
    Lifestyle.Scoped);

это может вызвать проблему при вызове Verify(), так как во время запуска приложения HttpContext.Current is null и HttpContextWrapper не позволяет передавать null в конструктор.

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

container.Register<HttpContextBase>(() =>
{
    var context = HttpContext.Current;
    if (context == null && container.IsVerifying) return new FakeHttpContext();
    return new HttpContextWrapper(context);
},
    Lifestyle.Scoped);

FakeHttpContext пустой HttpContextBase реализация для предотвращения возврата null в случае, если контейнер является проверка. The FakeHttpContext просто это:

public class FakeHttpContext : HttpContextBase { }

обратите внимание, однако, что HttpContext-это данные времени выполнения и инъекция данных времени выполнения в компоненты во время строительства является анти-шаблоном. Вместо того, чтобы вводить HttpContext или любую абстракцию поверх него в ваши компоненты, вы должны создать абстракцию для конкретного приложения это предоставляет потребителю то, что ему действительно нужно (например, идентификатор пользователя или идентификатор арендатора). Реализация этой абстракции может просто вызвать HttpContext.Ток внутри, который полностью предотвращает необходимость ввода HttpContext.