2009-03-16 9 views
2

die unter Konfiguration BeiSchloss Windsor Fluent API: Definieren Abhängigkeit explizit

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

Wenn ich weiß, dass die Schnittstelle „I“ eine Eigenschaft „P“ aussetzt, und dass die Klassen A und B bis P zugeordnet werden ; Wie stelle ich explizit fest, dass bei der ersten Auflistung von Typen aus dem AllTypes-Aufruf die Eigenschaft P auf den Typ mit der ID "foo" festgelegt werden soll und die zweite Auflistung dieselbe Eigenschaft auf den Typ mit der ID "foobar" haben soll "?

Mithilfe der XML-Konfiguration kann dies durch explizites Festlegen der Parameter in der $ {id} -Notation erfolgen. Ich nehme an, es ist ähnlich in der fließenden API.

Danke.

Antwort

2

Sie sind auf dem richtigen Weg - was Sie tun müssen, ist die Konfiguration der Parameter der einzelnen Komponenten, je nachdem, ob Sie den Parameter "P" mit dem Wert "$ {foo}" oder "$ {foobar}" angeben Szenario, hier ist eine funktionierende xunit Tatsache (scrollen Sie nach unten für den tatsächlichen Registrierungscode), die Ihr Szenario zeigt.

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

Hoffe, das hilft!

1

Eine Sache zu erwähnen, um dies zu testen.

Der zweite zu konfigurierende Anruf scheint den ersten Anruf abzubrechen.

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

Wenn Sie den Test

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

hinzufügen wird es scheitern, aber man würde erwarten, dass es auch passieren, wie alles vergänglich deklariert wird. Dies bedeutet, dass der vorübergehende Lebensstil verloren ging und stattdessen der Standard-Lebensstil von Singleton verwendet wurde.

Wenn Sie den Konfigurationsaufruf wie folgt ändern, wird ein Test bestanden.

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

Danke.

+0

Sie haben Recht - ich bin, wenn dieses ideale Verhalten seitens der fließenden Registrierung nicht sicher - in der Lage sein Eine vorherige Konfiguration zu überschreiben ist in einigen Szenarien nützlich, aber in den meisten Fällen wahrscheinlich etwas unerwartet! – Bittercoder

1

Eigentlich @ Bittercoder Der umfassende Antwort, die empfohlene Methode hinzuzufügen, es zu tun ist:

.DependsOn(Property.ForKey("P").Is("fooBar")) 
Verwandte Themen