2010-06-17 16 views
7

मैं अभी भी एकता कंटेनर का उपयोग करते हुए अपना खुद का अवरोध लागू करने की कोशिश कर रहा हूं। मैं ऐसा इस तरह से करना चाहता हूं जहां यह जीवनभर प्रबंधक का सम्मान करता है। यानी यदि यह एक PerResolveLifetimeManager है तो मैं एक बार उदाहरण को लपेटना चाहता हूं और मैं चाहता हूं कि उस संकल्प को पूरे संकल्प में उपयोग किया जाए।एकता कंटेनर: PerResolveLifetimeManager और कस्टम अवरोध का उपयोग

अब तक मैंने एक बिल्डरस्ट्रेटी को लागू किया है जिसे मैं एक कस्टम यूनिटीकॉन्टेनर एक्सटेंशन कक्षा का उपयोग करके अपने कंटेनर में जोड़ता हूं (मैं एडन्यू विधि में पोस्टइनाइजेशन को पास करता हूं; मुझे यकीन नहीं है कि सबसे उचित मूल्य क्या है लेकिन यह काम करने लग रहा था)। मेरे BuilderStrategy में PostBuildUp ओवरराइड में, मैं संदर्भ को प्रतिस्थापित करता हूं। मेरे लिपटे मूल्य के साथ।

जब मैं पेरसेल्व जीवनकाल के साथ इसका उपयोग करता हूं, तो एक रैप होता है लेकिन केवल निर्भरता का पहला उपयोग लपेटा हुआ उदाहरण प्राप्त करता है और बाकी को एक गैर लपेटा हुआ उदाहरण मिलता है। यानी अगर मेरा सीटीओ IFoo foo1 और IFoo foo2 में लेता है तो केवल foo1 मेरा लपेटा हुआ उदाहरण है जबकि foo2 अनचाहे उदाहरण है।

यहां नमूने रेप्रो (सादगी के लिए, मैं, एक और वर्ग, foo2 का एक उदाहरण का उपयोग कर रहा रैपिंग के बजाय):

public class MyInterception : UnityContainerExtension 
{ 
    protected override void Initialize() 
    { 
     Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.PostInitialization); 
    } 
} 

public class MyInterceptionStrategy : BuilderStrategy 
{ 
    public override void PostBuildUp(IBuilderContext context) 
    { 
     if (!context.OriginalBuildKey.Type.IsInterface) 
     { 
      return; 
     } 

     context.Existing = new Foo2(); 
    } 
} 

public class Bar 
{ 
    public Bar(IFoo f1, IFoo f2, IFoo f3) 
    { 
    } 
} 

public interface IFoo 
{ 
} 

public class Foo1 : IFoo 
{ 
} 

public class Foo2 : IFoo 
{ 
} 

public void Main() 
{ 
    UnityContainer container = new UnityContainer(); 
    container.AddNewExtension<MyInterception>(); 
    container.RegisterType(typeof (IFoo), typeof (Foo1), new PerResolveLifetimeManager()); 

    container.Resolve<Bar>(); 
} 

आप PostBuildUp में और बार के contructor और डिबग मुख्य में एक ब्रेकपाइंट डाल दिया बार के संकल्प के माध्यम से, आप देख सकते हैं कि PostBuildUp को केवल एक बार बुलाया जाता है। हालांकि, बार के कन्स्ट्रक्टर में, एफ 1 Foo2 का एक उदाहरण है (एक "लपेटा" उदाहरण) जबकि f2 और f3 Foo1 (अनचाहे) के उदाहरण हैं।

मैं सोच रहा था कि मैं क्या चाहता हूं और यदि मैं सही दृष्टिकोण ले रहा हूं? क्या मेरी समस्याएं जीवनकाल और/या यूनिटीबिल्डस्टेज से संबंधित हैं जिन्हें मैंने बिल्डरस्ट्रेटी को जोड़ा है?

धन्यवाद

+0

क्या आपका मतलब यूनिटी गेम इंजन है? –

+4

मेरा मानना ​​है कि वह कंटेनर में एकता का जिक्र कर रहा है http://unity.codeplex.com/ – aqwert

उत्तर

2

आप निर्माण रणनीति में बहुत देर हो चुकी अवरोधन रणनीति कर रहे हैं। दुर्भाग्यवश, इस समय मेरे पास क्यों के लिए अधिक विस्तृत कारण नहीं है, यह कोड ऑब्जेक्टबिल्डर असेंबली के अंदर इस तरह से व्यवहार कर रहा है।

उम्मीद है कि जब मैं एकता ObjectBuilder विश्लेषण करने के लिए और अधिक समय है, मैं वापस आ जाएगी, लेकिन इस दौरान आपके मुद्दे को हल करने के लिए, बस सेटअप या TypeMapping को PostInitialization से अपने UnityBuildStage गणन मान बदलने

Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.Setup); 

मेरा पूरा कोड:

using System; 
using Microsoft.Practices.ObjectBuilder2; 
using Microsoft.Practices.Unity; 
using Microsoft.Practices.Unity.ObjectBuilder; 

namespace UnityInterceptors 
{ 
    class Program 
    { 
     public class MyInterception : UnityContainerExtension 
     { 
      protected override void Initialize() 
      { 
       Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.Setup); 
      } 
     } 
     public class MyInterceptionStrategy : BuilderStrategy 
     { 
      public override void PostBuildUp(IBuilderContext context) 
      { 
       if (!context.OriginalBuildKey.Type.IsInterface) 
       { 
        return; 
       } 

       context.Existing = new Foo2(); 
      } 
     } 

     public class Bar 
     { 
      public Bar(IFoo f1, IFoo f2, IFoo f3) 
      { 
       Console.WriteLine(f1.GetType().Name); 
       Console.WriteLine(f2.GetType().Name); 
       Console.WriteLine(f3.GetType().Name); 
      } 
     } 

     public interface IFoo 
     { 
     } 

     public class Foo1 : IFoo 
     { 
     } 

     public class Foo2 : IFoo 
     { 
     } 

     public static void Main() 
     { 
      UnityContainer container = new UnityContainer(); 
      container.AddNewExtension<MyInterception>(); 
      container.RegisterType(typeof(IFoo), typeof(Foo1), new PerResolveLifetimeManager()); 

      container.Resolve<Bar>(); 

      Console.ReadLine(); 
     } 
    } 
} 
  • यह भी ध्यान दें कि मैं एकता 2.0 लाइब्रेरी का उपयोग कर रहा हूं। संभवतः कुछ प्रकार की बग हो सकती है जिसे हल किया गया है।
संबंधित मुद्दे