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

У меня есть интерфейс в основном проекте моего решения: 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?


person Declan McNulty    schedule 26.11.2012    source источник


Ответы (2)


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

person PatrickSteele    schedule 26.11.2012

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

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();
    }
}
person Declan McNulty    schedule 27.11.2012