Castle Windsor Fluent API: Define dependency explicitly

☆樱花仙子☆ 提交于 2019-12-04 15:33:30

You are on the right track - what you need to do is configure the parameters of each component, supplying the parameter named "P" with the value "${foo}" or "${foobar}" depending on your scenario, here's a working xunit fact (scroll down towards the bottom for the actual registration code) which demonstrates your scenario.

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

Hope this helps!

One thing to mention on testing this.

The second call to configure appears to cancel out the first call.

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

If you add to the test

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

it will fail, but you would expect it too pass as everything is declared transient. This implies the transient lifestyle was lost and the default lifestyle of singleton used instead.

Changing the configure call to the below results in a test pass.

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

Thanks.

Actually to add to @Bittercoder's comprehensive answer, the recommended way to do it is:

.DependsOn(Property.ForKey("P").Is("fooBar"))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!