2008-09-17 43 views
11

Ben Say Ben aynı şeyi yapıyor hakkında ancak kodda gideceğini nasılCastle Windsor: Koddan bir constructor parametresi nasıl belirlenir?

<component id="sample" service="NS.IMyComponent, WindsorSample" type="NS.MyComponent, WindsorSample"> 
    <parameters> 
    <start_at>1</start_at > 
    </parameters> 
</component> 

şöyle ben xml üzerinden kale windsor ile bunun bir örneğini kayıt olabilirsiniz

MyComponent : IMyComponent { 
    public MyComponent(int start_at) {...} 
} 

aşağıdaki sınıf? (Bildirim, yapıcı parametresi)

cevap

15

Düzenleme: ile kodunun altına cevapları Kullanılan Akıcı Arabirimi :)

namespace WindsorSample 
{ 
    using Castle.MicroKernel.Registration; 
    using Castle.Windsor; 
    using NUnit.Framework; 
    using NUnit.Framework.SyntaxHelpers; 

    public class MyComponent : IMyComponent 
    { 
     public MyComponent(int start_at) 
     { 
      this.Value = start_at; 
     } 

     public int Value { get; private set; } 
    } 

    public interface IMyComponent 
    { 
     int Value { get; } 
    } 

    [TestFixture] 
    public class ConcreteImplFixture 
    { 
     [Test] 
     void ResolvingConcreteImplShouldInitialiseValue() 
     { 
      IWindsorContainer container = new WindsorContainer(); 

      container.Register(
       Component.For<IMyComponent>() 
       .ImplementedBy<MyComponent>() 
       .Parameters(Parameter.ForKey("start_at").Eq("1"))); 

      Assert.That(container.Resolve<IMyComponent>().Value, Is.EqualTo(1)); 
     } 

    } 
} 
+1

Bu çözüm, parametre başka bir IMyComponent gibi karmaşık bir türse işe yarar mı? – flipdoubt

+0

Bağımlılık kapsayıcıda ise otomatik olarak çözülecektir –

+0

Ben akıcı bir arabirimi kullanmayı seviyorum, ancak kale kaynağını indirmeyi, (daha önce hiç kullanmadığım) nant'ı indirmeyi ve herşeyi anlamaya çalışıyorum biraz fazla –

0

Sen mesela kabını sorduğunuzda bir IDictionary içinde geçmesi gerekiyor.

T Resolve<T>(IDictionary arguments) 

veya olmayan jenerik bir:

object Resolve(Type service, IDictionary arguments) 

Yani, örneğin: (varsayarak kap bir IWindsorContainer olan)

Sen IWindsorContainer bu Çöz aşırı kullanmak istiyorum

IDictionary<string, object> values = new Dictionary<string, object>(); 
values["start_at"] = 1; 
container.Resolve<IMyComponent>(values); 

Sözlükteki anahtar değerlerin büyük/küçük harfe duyarlı olduğunu unutmayın.

+0

Maalesef Gareth deneyin ama bu yayınlanmıştır XML olarak aynı şey değildir. Burada, parametrenin çözücü tarafından bilinmesi gerekir, oysa söz konusu XML, bir varsayılan değer sağlar. Farklı bir sorunu çözmek için –

+0

+1 - çalışma zamanında aktarılan bir parametreyle bir nesneyi başlatmak. –

-1

Sen genişletilmiş özellikleri olan bir hizmet kayıt IWindsorContainer arabiriminin AddComponentWithProperties yöntemini kullanabilirsiniz.

Aşağıda, bir NUnit Birim Testi ile bunu yapmanın 'çalışan' bir örneğidir.

namespace WindsorSample 
{ 
    public class MyComponent : IMyComponent 
    { 
     public MyComponent(int start_at) 
     { 
      this.Value = start_at; 
     } 

     public int Value { get; private set; } 
    } 

    public interface IMyComponent 
    { 
     int Value { get; } 
    } 

    [TestFixture] 
    public class ConcreteImplFixture 
    { 
     [Test] 
     void ResolvingConcreteImplShouldInitialiseValue() 
     { 
      IWindsorContainer container = new WindsorContainer(); 
      IDictionary parameters = new Hashtable {{"start_at", 1}}; 

      container.AddComponentWithProperties("concrete", typeof(IMyComponent), typeof(MyComponent), parameters); 

      IMyComponent resolvedComp = container.Resolve<IMyComponent>(); 

      Assert.That(resolvedComp.Value, Is.EqualTo(1)); 
     } 

    } 
} 
+0

Sadece Bunu denemek için var, işe yaramaz: 'Beton' (WindsorSample.MyComponent) için isteğe bağlı bağımlılık giderilemedi. Parametre 'start_at' türü 'System.Int32' –

1

Konteynerinizi yapılandırmak için Binsor'u kullanmayı düşündünüz mü? Verbose ve hantal XML'den ziyade, Windsor'u Boo tabanlı bir DSL kullanarak yapılandırabilirsiniz. avantajı, bir dövülebilir yapılandırma dosyası var ama XML ile sorunları önlemek olduğunu

component IMyComponent, MyComponent: 
    start_at = 1 

: Burada gibi yapılandırma görüneceğini bu. Ayrıca, kabınızı kod olarak yapılandırdıysanız, yapılandırmanızı değiştirmek için yeniden derlemeniz gerekmez. Bunu here ile başlayabilirsiniz

for type in Assembly.Load("MyApp").GetTypes(): 
    continue unless type.NameSpace == "MyApp.Services" 
    continue if type.IsInterface or type.IsAbstract or type.GetInterfaces().Length == 0 
    component type.GetInterfaces()[0], type 

: Sıfır sürtünme yapılandırmasını sağlayan yardımcı yöntemler bol da var

.

+0

Kendime 3 saniyeden fazla ulaştığımda ona bir göz atmayı planlıyorum. Bu benim için de önemli olan bu yeniden derleme olmadan değiştirebileceğim bir şey olabilir çünkü –

2

bu

int start_at = 1; 
container.Register(Component.For().DependsOn(dependency: Dependency.OnValue(start_at))); 
+1

alandaki uygulamalarda hata ayıklamak için interceptors açmak/kapatmak için biraz daha açıklayabilir misiniz? –

+0

Bu, bir cevapta dürüst bir girişimdir ve bu yüzden bir yanıt olarak işaretlenmemelidir. Cevabı beğenmezseniz, onu reddetmelisiniz, bayraklamalısınız. – ArtOfWarfare

İlgili konular