2013-01-23 11 views
7

के साथ विभिन्न क्षेत्रों में विभिन्न घटकों को लौटाना मेरे पास दो स्कॉप्स हैं, जो एक दूसरे के अंदर घोंसला है। जब मैं किसी विशेष सेवा को हल करता हूं, तो मैं एक घटक को एक रूट स्कोप में हल करना चाहता हूं और बच्चे के दायरे में एक अलग होना चाहता हूं। क्या ऐसा करने का कोई आसान तरीका है?ऑटोफैक

मैं कुछ एक कारखाने वर्ग निर्धारित करता है कि क्या वर्तमान क्षेत्र है का उपयोग कर काम कर रहे और उसके बाद उपयुक्त उदाहरण लौट पाने में कामयाब रहे है

IContainer BuildContainer() 
{ 
    var builder = new ContainerBuilder(); 

    // ... 
    builder.RegisterType<FooInParentScope>().AsSelf(); 
    builder.RegisterType<FooInChildScope>().AsSelf(); 
    builder.RegisterType<FooFactory>().AsImplementedInterfaces(); 
    builder.Register<IFoo>(c => c.Resolve<IFooFactory>().GetFoo()).InstancePerLifetimeScope(); 
    // ... 
} 


class FooFactory : IFooFactory 
{ 
    private readonly ILifetimeScope m_scope; 

    public FooFactory(ILifetimeScope scope) 
    { 
     m_scope = scope; 
    } 

    public IFoo GetFoo() 
    { 
     if (m_scope.Tag == "ParentScope") 
      return m_scope.Resolve<FooInParentScope>(); 
     else 
      return m_scope.Resolve<FooInChildScope>(); 
    } 
} 

class FooInParentScope : IFoo 
{ 
} 

class FooInChildScope : IFoo 
{ 
} 

इस दृष्टिकोण के साथ मुद्दों की एक संख्या हैं:

  1. मुझे एक अतिरिक्त कक्षा (या 2 - सुनिश्चित नहीं है कि IFooFactory वास्तव में आवश्यक है)
  2. उपरोक्त कोड अन्य स्कॉप्स का सामना नहीं करता है जो अभिभावकस्कोप में घिरे हुए हैं। मैं इसे Autofac.Core.Lifetime.LifetimeScope पर दायरा कास्टिंग करके ParentLifetimeScope संपत्ति की जांच करके इसे ठीक कर सकता हूं, लेकिन शायद यह करना विशेष रूप से सुरक्षित नहीं है।

उत्तर

10

आप रूट कंटेनर में एकल इन्स्टेंस के रूप में FooInParentScope पंजीकृत कर सकते हैं। और आंतरिक जीवनकाल बनाने के दौरान FooInChildScope के लिए एकल प्रवेश (पंजीकरण ओवरराइड) के रूप में पंजीकरण जोड़ें।

builder.RegisterType<FooInParentScope>().As<IFoo>.SingleInstance(); 
var container = builder.Build(); 

var childScope = container.BeginLifetimeScope(innerBuilder => 
    { 
     // override registration for IFoo in child lifetime scope: 
     innerBuilder.RegisterType<FooInChildScope>().As<IFoo>().SingleInstance(); 
    }); 

FooInParentScope fooInParentScope = (FooInParentScope) container.Resolve<IFoo>(); 
FooInChildScope fooInChildScope = (FooInChildScope) childScope.Resolve<IFoo>(); 
+2

यह ऐसा करने का एक तरीका है जिसे मैंने नहीं सोचा था। नकारात्मकता यह है कि आपको इसे एक ही स्थान पर रखने के बजाय, दायरा बनाने के बिंदु पर कुछ अतिरिक्त पंजीकरण करना है। –

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