У Castle Windsor выбрать компонент на основе пространства имен типа запросчика - PullRequest
3 голосов
/ 05 декабря 2011

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

Пример регистрации моего компонента:

IWindsorContainer container = new WindsorContainer();

container.Register(Component.For<NHibernate.ISession>()
  .UsingFactoryMethod((kernel, creationContext) =>
  {
    NHibernate.ISession session = 
      new SessionFactoryForNamespace1()
        .Instance.GetSession();

    return session;
  })
  .LifestylePerWebRequest());

container.Register(Component.For<NHibernate.ISession>()
  .UsingFactoryMethod((kernel, creationContext) =>
  {
    NHibernate.ISession session = 
      new SessionFactoryForNamespace2()
        .Instance.GetSession();

    return session;
  })
  .LifestylePerWebRequest());

container.Register(Component.For<Namespace1.IRepository1()
  .ImplementedBy<Namespace1.Repository1>());

container.Register(Component.For<Namespace2.IRepository2>()
  .ImplementedBy<Namespace2.Repository2>());

Примерграфик разрешения:

public class MyController
{
    public MyController(Namespace1.IRepository1 repo1,
        Namespace2.IRepository2 repo2) { }
}

namespace Namespace1
{
    public interface IRepository1 { }
    public class Repository1 : IRepository1
    {
        public Repository1(NHibernate.ISession session) { }
    }
}

namespace Namespace2
{
    public interface IRepository2 { }
    public class Repository2 : IRepository2
    {
        public Repository2(NHibernate.ISession session) { }
    }
}

Когда Castle Windsor предлагается разрешить MyController, он пытается разрешить IRepository1 и IRepository2, а затем ISession для каждого.Я хочу, чтобы Castle Windsor выбирал обработчики компонентов на основе пространства имен типа запросчика, которое в моем примере является либо Namespace1, либо Namespace2.

Я новичок в Castle Windsor и не уверен, где в конвейере разрешения я долженподключиться к.

Каков наилучший подход для достижения того, что я обрисовал в общих чертах выше?

Ответы [ 2 ]

4 голосов
/ 05 декабря 2011

Я думаю, что переопределение службы подойдет для этого.

ОБНОВЛЕНИЕ:

Я также написал статью на некоторыхРасширенные функции Windsor (включая раздел о переопределениях служб), которые должны дополнять документацию, связанную выше.

1 голос
/ 07 декабря 2011

Вот как я реализовал решение по переопределению службы:

Интерфейсы репозитория теперь наследуются от общего интерфейса репозитория:

public class MyController
{
    public MyController(Namespace1.IRepository1 repo1,
        Namespace2.IRepository2 repo2) { }
}

public interface IRepository { }

namespace Namespace1
{
    public interface IRepository1 : IRepository { }
    public class Repository1 : IRepository1
    {
        public Repository1(NHibernate.ISession session) { }
    }
}

namespace Namespace2
{
    public interface IRepository2 : IRepository { }
    public class Repository2 : IRepository2
    {
        public Repository2(NHibernate.ISession session) { }
    }
}

Перерегистрация компонента репозитория в зависимости от его пространства имен:

IWindsorContainer container = new WindsorContainer();

...

Action<Type> RegisterRepository = t =>
{
    container.Register(
        AllTypes.FromAssemblyContaining(t)
            .BasedOn(typeof(IRepository))
            .WithServiceAllInterfaces()
            .Configure(c =>
            {
                c.DependsOn(
                    ServiceOverride
                        .ForKey<NHibernate.ISession>()
                        .Eq(c.Implementation.Namespace));

                c.LifeStyle.Is(LifestyleType.Transient);
            })
    );
};

RegisterRepository(typeof(Namespace1.IRepository1));
RegisterRepository(typeof(Namespace2.IRepository2));

Кажется, работает:)

...