2

鉴于以下配置

        Container.Register(Component.For<A>().Named("foo"));
        Container.Register(Component.For<B>().Named("foobar"));

        Container.Register(
            AllTypes.Pick()
            .FromAssemblyNamed("MyAssembly")
            .If(t => t.Name.EndsWith("ABC"))
            .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
            .WithService.Select(i => typeof(I))
        );

        Container.Register(
            AllTypes.Pick()
            .FromAssemblyNamed("MyAssembly")
            .If(t => t.Name.EndsWith("123"))
            .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
            .WithService.Select(i => typeof(I))
        );

如果我知道接口“I”公开了一个属性“P”,并且类 A 和 B 可以分配给 P;我如何明确声明来自 AllTypes 调用的第一个类型集合应该将属性 P 设置为 id 为“foo”的类型,而第二个集合应该将相同的属性设置为 id 为“foobar”的类型“?

使用 XML 配置,这可以通过使用 ${id} 符号显式设置参数来完成。我认为它在流畅的 API 中是相似的。

谢谢。

4

3 回答 3

2

您走在正确的轨道上 - 您需要做的是配置每个组件的参数,根据您的场景为名为“P”的参数提供值“${foo}”或“${foobar}”,这里有一个演示您的场景的工作 xunit 事实(向下滚动到底部以获取实际注册码)。

namespace Question651392
{
  public class First123 : I
  {
    public AbstractLetter P { get; set; }
  }

  public class Second123 : I
  {
    public AbstractLetter P { get; set; }
  }

  public class FirstABC : I
  {
    public AbstractLetter P { get; set; }
  }

  public class SecondABC : I
  {
    public AbstractLetter P { get; set; }
  }

  public interface I
  {
    AbstractLetter P { get; set; }
  }

  public abstract class AbstractLetter
  {
  }

  public class B : AbstractLetter
  {
  }

  public class A : AbstractLetter
  {
  }

  public class RegistrationFacts
  {
    [Fact]
    public void EnsureParametersCanBeSetWhenRegisteringComponentsInBulk()
    {
      WindsorContainer Container = new WindsorContainer();

      Container.Register(Component.For<A>().Named("foo"));
      Container.Register(Component.For<B>().Named("foobar"));

      Container.Register(
          AllTypes.Pick()
          .FromAssembly(GetType().Assembly)
          .If(t => t.Name.EndsWith("ABC"))
          .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
          .Configure(c=>c.Parameters(Parameter.ForKey("P").Eq("${foo}")))
          .WithService.Select(new[] { typeof(I) })          
      );

      Container.Register(
          AllTypes.Pick()
          .FromAssembly(GetType().Assembly)
          .If(t => t.Name.EndsWith("123"))
          .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
          .Configure(c => c.Parameters(Parameter.ForKey("P").Eq("${foobar}")))
          .WithService.Select(new[] { typeof(I)})
      );

      var all = Container.ResolveAll<I>();

      var firstABC = all.Single(i => i is FirstABC);
      Assert.IsType(typeof(A), firstABC.P);

      var first123 = all.Single(i => i is First123);
      Assert.IsType(typeof (B), first123.P);

      Assert.Equal(4, all.Count());
    }
  }
}

希望这可以帮助!

于 2009-03-17T09:20:53.990 回答
1

在测试这个时要提一件事。

对配置的第二次调用似乎取消了第一次调用。

      .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
      .Configure(c => c.Parameters(Parameter.ForKey("P").Eq("${foobar}")))

如果你添加到测试

        var all2 = Container.ResolveAll<I>();
        Assert.IsTrue(all.Count(i => all2.Contains(i)) == 0);

它会失败,但你会期望它也会通过,因为一切都被宣布为瞬态。这意味着短暂的生活方式丢失了,而是使用了默认的单身生活方式。

将配置调用更改为以下会导致测试通过。

        .Configure(c => .LifeStyle.Is(LifestyleType.Transient).Parameters(Parameter.ForKey("P").Eq("${foobar}")))

谢谢。

于 2009-03-17T17:45:51.827 回答
1

实际上要添加到@Bittercoder 的综合答案,推荐的方法是:

.DependsOn(Property.ForKey("P").Is("fooBar"))
于 2011-04-23T03:06:36.523 回答