Использование контейнера IoC в качестве локатора службы для HttpHandler

Этот вопрос относится к моему другому сообщению .

Итак, немного повозившись, я решил сделать это таким образом. Что, кажется, работает нормально, когда я запускаю его, хотя я получаю следующую ошибку в NUnit: не удалось загрузить файл или сборку «Castle.Core, версия = 1.0.3.0, культура = нейтральная, PublicKeyToken = 407dd0808d44fbdc» или один из его зависимости. Определение манифеста обнаруженной сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040) Так что не знаете, что там происходит???

Просто хотел узнать, что другие думают о дизайне и есть ли какие-то очевидные «нет-нет» или улучшения. т.е. Является ли конструктор базового обработчика хорошим местом для создания экземпляра компонента Windsor или есть лучшее место для этого? Как я уже говорил в исходном посте, идея такого подхода заключалась в том, чтобы компоненты были хорошо отделены друг от друга и чтобы упростить модульное тестирование. Я также должен добавить, что я новичок в модульном тестировании, издеваясь. Спасибо!

public abstract class BaseHttpHandler : IHttpHandler
{
    private HttpContext _httpContext;
    private ILogger _logger;
    private IDataRepository _dataRepository;
    protected HttpRequest Request { get { return _httpContext.Request; } }
    protected HttpResponse Response { get { return _httpContext.Response; } }
    protected bool IsRequestFromUAD { get { return Request.UserAgent == null ? false : Request.UserAgent.Equals("UAD"); } }
    protected ILogger Logger { get { return _logger; } }
    protected IDataRepository DataRepository { get { return _dataRepository; } }
    public virtual bool IsReusable { get { return false; } }

    public BaseHttpHandler()
    {
        var container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
        _logger = container.Resolve<ILogger>();
        _dataRepository = container.Resolve<IDataRepository>();
    }

    public void ProcessRequest(HttpContext context)
    {
        _httpContext = context;
        ProcessRequest(new HttpContextWrapper(context));
    }

    public abstract void ProcessRequest(HttpContextBase context);
}

public class UADRecordHttpHandler : BaseHttpHandler
{
    public override void ProcessRequest(HttpContextBase context)
    {
        if (IsRequestFromUAD)
        {
            using (var reader = new StreamReader(context.Request.InputStream))
            {
                string data = reader.ReadToEnd();

                if (Logger != null)
                    Logger.Log(data);

                if(DataRepository != null)
                    DataRepository.Write(data);

                context.Response.Write(data);
            }
        }
        else
            ReturnResponse(HttpStatusCode.BadRequest);
    }
}

person Id10T-ERROR    schedule 23.08.2010    source источник


Ответы (2)


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

person Krzysztof Kozmic    schedule 23.08.2010
comment
Привет. Спасибо за ваш ответ. Это имеет смысл (именно так я и думал, я думал, что было бы лучше создать контейнер где-нибудь еще, например Application_Start (Global.asax.cs), но даже если я создам статический локатор службы, как предлагает Маурисио ниже, как HttpHandler получает доступ к контейнеру? - person Id10T-ERROR; 24.08.2010

По поводу ошибки в NUnit: убедитесь, что у вас нет других версий сборок Castle в GAC. Если это так, удалите их.

О вашем BaseHttpHandler: проблема с этой реализацией заключается в том, что вы создаете новый контейнер. Вместо этого используйте один контейнер для каждого приложения, как сказал Кшиштоф. Используйте статический локатор сервисов, например. CommonServiceLocator. (Я никогда не рекомендую это, но это одно из немногих мест, где это имеет смысл).

person Mauricio Scheffer    schedule 23.08.2010
comment
Могу ли я просто добавить контейнер в HttpApplicationState?? protected void Application_Start (отправитель объекта, EventArgs e) { Application.Add (Контейнер, новый WindsorContainer (новый XmlInterpreter (новый ConfigResource (замок))))); } - person Id10T-ERROR; 24.08.2010
comment
Спасибо за ваш вклад. Что касается проблемы со сборкой Castle.Core, я проверил GAC, и его там действительно нет? - person Id10T-ERROR; 24.08.2010
comment
Или вы думаете, что я должен открыть новый вопрос об этом? - person Id10T-ERROR; 24.08.2010
comment
@Matt: дважды проверьте свои ссылки. Там какая-то неправильная ссылка. Castle.Core 1.0.3.0 — очень старый релиз. - person Mauricio Scheffer; 24.08.2010
comment
Только для тех, кто может это читать. Проблема заключалась в том, что Moq ссылался на устаревшую dll. Спасибо за помощь, Маурисио. - person Id10T-ERROR; 24.08.2010