让Castle Windsor根据请求者类型命名空间选择组件

时间:2011-12-05 10:40:45

标签: castle-windsor

我有一个接口ISession,其实例由不同的Session Factory生成,具体取决于该类所属的命名空间。

我的组件注册示例:

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 个答案:

答案 0 :(得分:4)

我认为service override可以解决这个问题。

<强>更新

我还做了一个article on some of Windsor's advanced features(包括一个关于服务覆盖的部分),它应该增加上面链接的文档。

答案 1 :(得分:1)

以下是我实施服务覆盖解决方案的方法:

存储库接口现在继承自公共存储库接口:

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));

似乎工作:)