Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Castle Windsor разрешает неправильную реализацию интерфейса для области MVC

Автор вопроса: Declan McNultyОтветов: 2

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

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

 container.Register(AllTypes
                         .FromAssemblyNamed("MySolution.MyProject")
                               .Where(t => t.Name.EndsWith("Manager"))
                               .WithService.DefaultInterface()
                               .Configure(x => x.LifeStyle.PerWebRequest)
            );

После регистрации, когда я получаю обработчики в ядре для интерфейса IPersonManager, я получаю следующее:

{Castle.MicroKernel.IHandler[2]}
[0]: Model: {MySolution.Core.Interfaces.Services.IPersonManager}
/ {MySolution.Area1.PersonManager}

[1]: Model: {MySolution.Core.Interfaces.Services.IPersonManager}
/ {MySolution.Area2.PersonManager}

Итак, я вижу, что обе реализации зарегистрированы.

Проблема в том, что когда я нахожусь в Area2 на веб-сайте, Windsor разрешает реализацию интерфейса Area1, а не Area2.

Похоже, Виндзор просто возвращает мне тот, который был зарегистрирован первым. Есть ли способ вернуть правильную реализацию на основе области MVC?

model-view-controllercastle-windsorinversion-of-controlioc-container

Ответы

Ответ 1 · рейтинг 1 · PatrickSteele

Я бы рассмотрел для этого IHandlerSelector. Вы можете изучить текущий контекст HTTP-запроса и "помочь" Windsor решить, какую реализацию использовать.

Ответ 2 · Declan McNulty

Пошел с предложением Патрика, вот код:

public class PersonManagerHandlerSelector : IHandlerSelector
{
    public bool HasOpinionAbout(string key, System.Type service)
    {
        return service == typeof (IPersonManager);
    }

    public IHandler SelectHandler(string key, System.Type service,
                                                         IHandler[] handlers)
    {
        var dataTokens = System.Web.HttpContext.Current.Request.
                                          RequestContext.RouteData.DataTokens;
        if (dataTokens.Any())
        {
            var area = System.Web.HttpContext.Current.Request.RequestContext.
                                                   RouteData.DataTokens["area"];

            return !string.IsNullOrEmpty(area.ToString())
                       ? handlers.First(x =>
                                     x.ComponentModel.Name.Contains("." + area))
                       : handlers.First();
        }
        return handlers.First();
    }
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы