2012-02-22 12 views
7

कैसल विंडसर एक स्ट्रिंग पैरामीटर द्वारा फ़िल्टर किए गए संग्रह को हल कर सकता है?फ़िल्टरिंग पैरामीटर के साथ संग्रह को कैसे हल करें?

interface IViewFactory 
{ 
    IView[] GetAllViewsInRegion(string regionName); 
} 

मेरा एप्लिकेशन क्षेत्रों को IView- व्युत्पन्न प्रकारों के समूह के रूप में परिभाषित करता है। जब मैं रनटाइम पर एक विशेष क्षेत्र प्रदर्शित करता हूं, तो मैं इसके भीतर प्रत्येक IView प्रकार (एक ला प्रिज्म) का एक उदाहरण हल करना चाहता हूं।

मैंने इसे कैसल की टाइपेड फैक्ट्री सुविधा, घटक मॉडेल कंस्ट्रक्शन योगदानकर्ता, और हैंडलर चयनकर्ताओं के साथ करने का प्रयास किया है, लेकिन मैं यह नहीं समझ सकता कि कैसल किस तरह से पहुंच सकता है, और न ही कैसे एक स्ट्रिंग में एकाधिक प्रकारों को मैप करना है स्ट्रिंग को जांचने के लिए कैसल का विस्तार करने के लिए जब यह तय करता है कि कौन से प्रकार कंटेनर में हल करने और वापस आने का प्रयास करें।

उत्तर

1

स्ट्रिंग द्वारा चयन कड़ाई से जरूरी है? क्या एक ही "क्षेत्र" में सभी IView कार्यान्वयन के बजाय IView से प्राप्त एक समर्पित इंटरफ़ेस को लागू करना संभव होगा? फिर आप क्षेत्र के लिए कार्यान्वयन को हल करने के लिए WindsorContainer.ResolveAll() (अपने क्षेत्र-विशिष्ट IView को टी के रूप में पास कर सकते हैं) का उपयोग कर सकते हैं (या आप कन्स्ट्रक्टर इंजेक्शन करने के लिए संग्रह संकल्प में से एक का उपयोग कर सकते हैं)।

सामान्यतः, विंडसर के साथ इस तरह की चीजों को करने का प्रयास करते समय, मैं स्ट्रिंग-आधारित समाधानों का उपयोग करने से पहले टाइप सिस्टम (और विंडसर का समर्थन) का उपयोग करने के लिए हर संभव प्रयास करता हूं।

अद्यतन: के बाद से हम पुष्टि की है कि स्ट्रिंग द्वारा चयन इस मामले में आवश्यक है, सबसे अच्छा समाधान मैं देख रहा हूँ बस, कर्नेल कि IVIEW सेवा को संतुष्ट में संचालकों की सूची का निरीक्षण किया तो इसको लागू करने के लिए फिल्टर करने के लिए है, जहां क्षेत्र (विशेषता के माध्यम से परिभाषित) हम जो चाहते हैं उससे मेल खाते हैं, फिर उन कार्यान्वयनकर्ताओं को हल करें। यह थोड़ा सा हैशिश महसूस करता है, लेकिन यदि आप अपने IViewFactory कार्यान्वयन में कंटेनर का सीधा संदर्भ रखने के ठीक हैं, तो यह ठीक काम करता प्रतीत होता है। नीचे समाधान का प्रदर्शन करने वाला एक उत्तीर्ण परीक्षण मामला है।

[Test] 
    public void Test() 
    { 
     using (var factory = new ViewFactory()) 
     { 

      var regionOneViews = factory.GetAllViewsInRegion("One"); 
      Assert.That(regionOneViews, Is.Not.Null); 
      Assert.That(regionOneViews, Has.Length.EqualTo(2)); 
      Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneA>()); 
      Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneB>()); 

      var regionTwoViews = factory.GetAllViewsInRegion("Two"); 
      Assert.That(regionTwoViews, Is.Not.Null); 
      Assert.That(regionTwoViews, Has.Length.EqualTo(1)); 
      Assert.That(regionTwoViews, Has.Some.TypeOf<RegionTwoA>()); 
     } 
    } 
} 

public interface IViewFactory 
{ 
    IView[] GetAllViewsInRegion(string regionName); 
} 

public class ViewFactory : IViewFactory, IDisposable 
{ 
    private readonly WindsorContainer _container; 

    public ViewFactory() 
    { 
     _container = new WindsorContainer(); 
     _container.Register(
      Component.For<IView>().ImplementedBy<RegionOneA>(), 
      Component.For<IView>().ImplementedBy<RegionOneB>(), 
      Component.For<IView>().ImplementedBy<RegionTwoA>() 
      ); 
    } 

    public IView[] GetAllViewsInRegion(string regionName) 
    { 
     return _container.Kernel.GetHandlers(typeof (IView)) 
      .Where(h => IsInRegion(h.ComponentModel.Implementation, regionName)) 
      .Select(h => _container.Kernel.Resolve(h.ComponentModel.Name, typeof (IView)) as IView) 
      .ToArray(); 
    } 

    private bool IsInRegion(Type implementation, 
          string regionName) 
    { 
     var attr = 
      implementation.GetCustomAttributes(typeof (RegionAttribute), false).SingleOrDefault() as RegionAttribute; 
     return attr != null && attr.Name == regionName; 
    } 

    public void Dispose() 
    { 
     _container.Dispose(); 
    } 
} 

public interface IView {} 

[Region("One")] 
public class RegionOneA : IView {} 

[Region("One")] 
public class RegionOneB : IView {} 

[Region("Two")] 
public class RegionTwoA : IView {} 

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
public class RegionAttribute : Attribute 
{ 
    private readonly string _name; 

    public RegionAttribute(string name) 
    { 
     _name = name; 
    } 

    public string Name 
    { 
     get { return _name; } 
    } 
} 
+0

मैं बजाय स्ट्रिंग कुंजी भी प्रकार का उपयोग करने की कोशिश, लेकिन प्रिज्म विस्तार बिंदु मैं (RegionBehavior) के साथ काम कर रहा हूँ तार के साथ क्षेत्रों एकत्रित करती है, तो मैं स्ट्रिंग द्वारा चयन के आसपास किसी भी तरह से नहीं देख सकता। हकीकत में, प्रिज्म केवल क्षेत्र में वस्तुओं की अपेक्षा करता है, इसलिए आईवी व्यू इंटरफ़ेस भी मेरे हिस्से पर एक कृत्रिम सरलीकरण है। [संशोधन 1] में (http://stackoverflow.com/revisions/9394391/1) मैंने अपने प्रश्न के संदर्भ का एक गुच्छा दिया, लेकिन मुझे लगता है कि यह लोगों को डरा रहा था। –

+0

कुछ क्षेत्रों को प्लगइन में परिभाषित किया गया है। चीजें बहुत जटिल और धीमी हो जाती हैं अगर मेरी कक्षा को छोटे नाम '' I '+ क्षेत्रनाम + "व्यू" के साथ मार्कर इंटरफ़ेस के लिए लोड असेंबली खोजनी हों। मैं 'व्यूएक्सपोर्ट [क्षेत्रनाम = "मेनरेगियन"]' जैसे कस्टम एट्रिब्यूट के साथ सजाने वाले वर्गों को पसंद करूंगा और विंडसर के हैंडलरफिल्टर एक्सटेंशन पॉइंट जैसे कुछ प्रकार के फ़िल्टर प्रकारों को फ़िल्टर करूंगा। –

+0

ठीक है मैं समझता हूं, मैं प्रिज्म से परिचित नहीं हूं, इसलिए मुझे एहसास नहीं हुआ कि स्ट्रिंग चयन आवश्यक था। मुझे लगता है कि ऐसा कुछ संभव होना चाहिए। मैं आज अपने खाली समय में कुछ के साथ आने की कोशिश करूंगा :-) –