2008-09-17 15 views
11

मेरे पास कहने के निम्नलिखित वर्गकैसल विंडसर: कोड से कन्स्ट्रक्टर पैरामीटर कैसे निर्दिष्ट करें?

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

मैं एक उदाहरण यह महल विंडसर साथ एक्सएमएल के माध्यम से के रूप में

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

मैं कैसे सटीक एक ही बात करने के बारे में है, लेकिन कोड में जाना होगा इस प्रकार रजिस्टर कर सकते हैं? (नोटिस, कन्स्ट्रक्टर पैरामीटर)

उत्तर

15

संपादित करें: के साथ कोड नीचे दिए गए उत्तर प्रयुक्त Fluent इंटरफ़ेस :)

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

क्या यह समाधान काम करता है यदि पैरामीटर एक जटिल प्रकार है, जैसे कि अन्य IMyComponent? – flipdoubt

+0

यदि निर्भरता कंटेनर में है तो इसे स्वचालित रूप से हल किया जाएगा –

+0

मुझे एक धाराप्रवाह इंटरफ़ेस का उपयोग करना अच्छा लगेगा, हालांकि महल स्रोत, नेंट (जिसे मैंने पहले कभी नहीं उपयोग किया है) डाउनलोड करना और इसे सब कुछ समझना थोड़ा सा –

0

जब आप उदाहरण के लिए कंटेनर पूछते हैं तो आपको एक आईडीकी में पास करने की आवश्यकता होती है। (यह मानते हुए कंटेनर एक IWindsorContainer है)

:

T Resolve<T>(IDictionary arguments) 

या गैर सामान्य से एक:

object Resolve(Type service, IDictionary arguments) 

तो, उदाहरण के लिए

आप IWindsorContainer के इस हल अधिभार का उपयोग करेंगे

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

ध्यान दें कि शब्दकोश में प्रमुख मान केस संवेदनशील हैं।

+0

क्षमा गैरेथ प्रयास करें, लेकिन इस एक्सएमएल मैं पोस्ट के रूप में एक ही बात नहीं है। यहां पैरामीटर को रिज़ॉल्यूवर द्वारा जाना जाना चाहिए जबकि सवाल में एक्सएमएल एक डिफ़ॉल्ट मान प्रदान करता है। –

+0

+1 एक अलग समस्या को हल करने के लिए +1 - रनटाइम पर पारित पैरामीटर के साथ ऑब्जेक्ट को तुरंत चालू करना। –

-1

आप विस्तारित गुणों के साथ एक सेवा रजिस्टर करने के लिए IWindsorContainer इंटरफ़ेस का AddComponentWithProperties विधि का उपयोग कर सकते हैं।

नीचे एनयूनीट यूनिट टेस्ट के साथ ऐसा करने का 'काम करने वाला' नमूना है।

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

है इसे करने के लिए चारों ओर मिल गया, यह काम नहीं करता है: 'कंक्रीट' (WindsorSample.MyComponent) के लिए गैर-वैकल्पिक निर्भरता को हल नहीं कर सका। पैरामीटर 'start_at' प्रकार 'System.Int32' –

1

क्या आपने अपने कंटेनर को कॉन्फ़िगर करने के लिए बिन्सर का उपयोग करने पर विचार किया है? वर्बोज़ और बेकार एक्सएमएल की बजाय आप बूओ आधारित डीएसएल का उपयोग कर विंडसर को कॉन्फ़िगर कर सकते हैं। लाभ

component IMyComponent, MyComponent: 
    start_at = 1 

आप एक लचीला कॉन्फ़िग फ़ाइल है, लेकिन XML के साथ समस्याओं से बचने के है जो: यहाँ अपने config दिखेगा की तरह है। इसके अलावा आपको अपनी कॉन्फ़िगरेशन को बदलने के लिए पुन: संकलित करने की आवश्यकता नहीं है जैसे आप कोड में कंटेनर कॉन्फ़िगर करते हैं।

वहाँ भी है सहायक तरीकों के बहुत सारे है कि शून्य घर्षण विन्यास सक्षम:

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 

आप इसे here के साथ आरंभ कर सकते हैं।

+0

जब मुझे अपने लिए 3 सेकंड से अधिक समय मिलता है तो मैं इसे देखने की योजना बना रहा हूं। मेरे लिए यह भी महत्वपूर्ण है कि यह कुछ ऐसा हो जो मैं बिना किसी संकलन के बदल सकता हूं क्योंकि मैं क्षेत्र में ऐप्स को डीबग करने के लिए इंटरसेप्टर्स को चालू/बंद करने की योजना बना रहा हूं –

2

इस

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

क्या आप थोड़ा आगे बता सकते हैं? –

+0

यह एक उत्तर में एक ईमानदार प्रयास है और इसलिए उत्तर के रूप में फ़्लैग नहीं किया जाना चाहिए। अगर आपको जवाब पसंद नहीं है, तो आपको इसे कम करना चाहिए, इसे ध्वजांकित नहीं करना चाहिए। – ArtOfWarfare

संबंधित मुद्दे