2009-03-16 2 views
2

Учитывая приведенную ниже конфигурациюЗамок Виндзор Fluent API: Определить зависимость явно

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

Если я знаю, что интерфейс «Я» предоставляет свойство «P», а также о том, что классы А и В могут быть отнесены к Р ; как явным образом заявляю, что первая коллекция типов из вызова AllTypes должна иметь свойство P, заданное типом с идентификатором «foo», а вторая коллекция должна иметь то же свойство, что и тип с идентификатором «foobar «?

Использование конфигурации XML это может быть сделано путем явной настройки параметров с использованием нотации $ {id}. Я предполагаю, что он похож на свободный API.

Спасибо.

ответ

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

Надеюсь, это поможет!

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

он потерпит неудачу, но можно было бы ожидать, что тоже пройдет, как и все объявляется переходный. Это означает, что переходный образ жизни был потерян, и вместо него использовался стиль жизни, используемый по умолчанию.

Изменение вызова конфигурации на нижеследующее приводит к прохождению теста.

Спасибо.

+0

Вы правы - я не уверен, если это идеальное поведение со стороны беглого регистрации - возможность для переопределения предыдущей конфигурации удобно в некоторых сценариях, но, вероятно, в большинстве случаев это немного неожиданно! – Bittercoder

1

На самом деле, чтобы добавить @ исчерпывающий ответ Bittercoder в, рекомендуемый способ сделать это:

.DependsOn(Property.ForKey("P").Is("fooBar")) 
Смежные вопросы