7

у нас есть класс с зависимостью от HttpContext. Мы реализовали это так:Как реализовать эту зависимость (HttpContext) в Unity?

public SiteVariation() : this(new HttpContextWrapper(HttpContext.Current)) 
{ 
} 
public SiteVariation(HttpContextBase context) 
{} 

Теперь то, что я хочу сделать, это создать экземпляр класса SiteVariation через Unity, так что мы можем создать один конструктор. Но я не знаю, как настроить этот новый HttpContextWrapper(HttpContext.Current)) в Unity в режиме конфигурации.

пс это конфигурация, как мы используем

<type type="Web.SaveRequest.ISaveRequestHelper, Common" mapTo="Web.SaveRequest.SaveRequestHelper, Common" /> 

ответ

11

Я бы не зависимость от HttpContextBase напрямую. Я бы вместо того, чтобы создать оболочку вокруг нее, и использовать биты нужно:

public interface IHttpContextBaseWrapper 
{ 
    HttpRequestBase Request {get;} 
    HttpResponseBase Response {get;} 
    //and anything else you need 
} 

то реализация:

public class HttpContextBaseWrapper : IHttpContextBaseWrapper 
{ 
    public HttpRequestBase Request {get{return HttpContext.Current.Request;}} 
    public HttpResponseBase Response {get{return HttpContext.Current.Response;}} 
    //and anything else you need 
} 

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

public SiteVariation(IHttpContextBaseWrapper context) 
{ 

} 

var container = new UnityContainer(); 
container.RegisterType<IHttpContextBaseWrapper ,HttpContextBaseWrapper>(); 
+0

Ницца. Был обеспокоен оберткой, потому что все, кажется, обернуто в эти дни, но в этом случае это кажется хорошим. – Michel

+1

О «все, кажется, обернуто в эти дни»: я слышал, как кто-то сказал: каждый год мы добавляем новые обертки вокруг дерьмового кода, который мы построили в прошлом году. Это не имеет никакого отношения к ответу, который хорош, но он просто появился :-) – Michel

+4

@Michel: В этом утверждении есть много правды. С DI/IoC, являющимся ароматом дня, я пишу обертки вокруг большого количества «устаревшего» кода (код, который в некоторых случаях не старше пары лет), чтобы сделать его более проверяемым. Сейчас кажется, что это правильно. Через 3 года мы все будем говорить: «Человек, WTF мы думали со всеми этими одноразовыми интерфейсами!» – BFree

24

Microsoft уже построил большие обертки и абстракций вокруг HttpContext, HttpRequest и HttpResponse, которая включена в .NET, так что я бы определенно использовать тех, кто непосредственно, а не упаковка это я сам.

Вы можете настроить Unity для HttpContextBase с помощью InjectionFactory, как это:

var container = new UnityContainer(); 

container.RegisterType<HttpContextBase>(new InjectionFactory(_ => 
    new HttpContextWrapper(HttpContext.Current))); 

Кроме того, если вам нужно HttpRequestBase (который я предпочитаю использовать самый) и HttpResponseBase, вы можете зарегистрировать их как это:

container.RegisterType<HttpRequestBase>(new InjectionFactory(_ => 
    new HttpRequestWrapper(HttpContext.Current.Request))); 

container.RegisterType<HttpResponseBase>(new InjectionFactory(_ => 
    new HttpResponseWrapper(HttpContext.Current.Response))); 

Вы можете легко издеваться HttpContextBase, HttpRequestBase и HttpResponseBase в модульных тестов без пользовательских оберток.

+2

Ваш ответ велик, так что это чисто стилистическая альтернатива: потому что вы возвращаете простой объект в lamda, вам не нужен формальный блок кода. Таким образом, вы можете просто написать одну строку: container.RegisterType (новый InjectionFactory (c => новый HttpContextWrapper (HttpContext.Текущий))); – BlackjacketMack

+2

@BlackjacketMack Спасибо! Да, мне это нравится. Я обновил ответ с этим. Чтобы следовать соглашению, я также обновился, чтобы использовать подчеркивание, чтобы указать, что этот параметр не используется. –

+2

Ницца. Это первый раз, когда я видел конвенцию о подчеркивании, но мне это нравится! Очень коммуникативный. – BlackjacketMack