Использование контейнера IoC в качестве локатора службы для HttpHandler - PullRequest
1 голос
/ 24 августа 2010

Этот вопрос относится к моей другой записи .

Хорошо, так что после еще большего возни я решил сделать это таким образом. Который, кажется, работает хорошо, когда я запускаю его, хотя я получаю следующую ошибку в NUnit: не удалось загрузить файл или сборку 'Castle.Core, версия = 1.0.3.0, Culture = нейтральный, 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);
    }
}

Ответы [ 2 ]

1 голос
/ 24 августа 2010

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

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

1 голос
/ 24 августа 2010

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

...