2010-07-07 13 views
25

के लिए एक ही उदाहरण लौटें मैं निम्नलिखित कोड के साथ घटकों को पंजीकृत कर रहा हूँ:कई इंटरफेस

StandardKernel kernel = new StandardKernel(); 

string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location) 
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory)) 
     continue; 

    foreach (var type in assembly.GetTypes()) 
    { 
     if (!type.IsComponent()) 
      continue; 

     foreach (var @interface in type.GetInterfaces()) 
     kernel.Bind(@interface).To(type).InSingletonScope(); 
    } 
} 

तो मैं एक वर्ग है जो दो इंटरफेस लागू करता है:

class StandardConsole : IStartable, IConsumer<ConsoleCommand> 

अगर मैं IStartable हल मैं एक मिल उदाहरण के लिए, अगर मैं IConsumer<ConsoleCommand> हल करता हूं तो मुझे दूसरा मिलता है।

मैं दोनों इंटरफेस के लिए एक ही उदाहरण कैसे प्राप्त करूं?

+1

यह प्रश्न दो में विभाजित किया जाना चाहिए, एक निनजेक्ट के लिए और दूसरा ऑटोफैक के लिए। –

+0

@ जेफवाल्कर कोडरेंजर: आपने इसके लिए -1 दिया? :) – jgauffin

+1

निनजेक्ट पक्ष पर 3 या 4 डुप्लिकेट हैं, http://stackoverflow.com/questions/3147996/binding-singleton-to-multiple-services-in-ninject उस आधार पर हटाए गए निंजा टैग को देखें। प्रश्न से निंजात्मक पहलू को हटाने का सुझाव दें क्योंकि यह एक अप्रत्याशित प्रश्न –

उत्तर

49
builder.RegisterType<StandardConsole>() 
    .As<IStartable>() 
    .As<IConsumer<ConsoleCommand>>() 
    .SingleInstance(); 

बहुत व्यापक रूप से इस्तेमाल की सुविधा किसी भी समस्याओं फिर वहाँ कहीं एक बग :)

HTH निक

संपादित तक है ऐसा लगता है, आप As() के अधिभार के बाद हैं जो एक आईनेमरेबल < टाइप >() - IntelliSense का उपयोग करके सभी As() अधिभारों को देखें, कुछ आपके परिदृश्य में फिट होना चाहिए। जैसा कि एक और टिप्पणीकर्ता ने नोट किया, आपको सभी जानकारी के साथ प्रश्न को अपडेट करने की आवश्यकता है।

+0

नहीं, मैं IENumerable का उपयोग करके पंजीकरण नहीं करना चाहता हूं। यह ऑटोफैक में एक निर्मित सुविधा है। साथ ही, मैं जेनेरिक पैरामीटर का उपयोग नहीं कर सकता क्योंकि मैं सभी घटकों को पंजीकृत करने के लिए प्रतिबिंब का उपयोग कर रहा हूं। – jgauffin

+2

मुझे आपकी विशेषता का पता है (मैंने इसे लिखा है;)) - जो मैं सुझाव दे रहा हूं वह अलग है। यदि आपके पास उन इंटरफेस की एक सूची है जो आप बेनकाब करना चाहते हैं (i1, i2, i3 ..) तो आप पूरी सूची को केवल एक ही() कॉल पर पास कर सकते हैं। आप RegisterAssemblyTypes (myAsm) भी देख सकते हैं .इस कार्यान्वित इंटरफेस(), जिसे आपके लेख का प्रस्ताव देने के लिए बढ़ाया जा सकता है http://code.google.com/p/autofac/wiki/Scanning - आप के माध्यम से काम करने के लिए आपका स्वागत है यदि आप चाहें तो ऑटोफैक चर्चा मंच के माध्यम से। –

+0

क्षमा करें =) बस उन लोगों के उत्तर से थक गए जिन्होंने ऑटोफैक का उपयोग नहीं किया था। मैंने स्कैनिंग आलेख से कोड के साथ नीचे अपना उत्तर अपडेट कर दिया है। धन्यवाद! – jgauffin

0

यह मुझे अंधेरे में जंगली स्टैब ले रहा है क्योंकि मुझे ऑटोफैक नहीं पता है।

जोड़ते हैं:

build.RegisterType<StandardConsole>.As(StandardConsole).SingleInstance() 

तो यह StandardConsole की सिंगलटन उदाहरण के लिए तो StandardConsole StandardConsole को IStartable को हल नहीं करना चाहिए? आईसीओएसयूमेर के साथ डितो।

संपादित करें: अपने ब्लॉग पर लॉग इन करने से, नहीं तो आपको निम्न को बदल सकता है:

assemblies.Each(assembly => assembly.FindComponents((i, c) => builder.RegisterType(c).As(i).SingleInstance())); 

assemblies.Each(assembly => assembly.FindComponents((i, c) => { 
    builder.RegisterType(c).As(i).SingleInstance(); 
    builder.RegisterType(c).As(c).SingleInstance(); 
})); 
+0

के लिए बनाता है डेव थिबेन – jgauffin

0

को मैं Autofac से परिचित नहीं हूँ, लेकिन आप के लिए सक्षम होना चाहिए एक प्रकार के लिए एक लैम्ब्डा अभिव्यक्ति के लिए पंजीकरण करें जो दूसरे प्रकार के समाधान को लौटाता है।

कुछ की तरह: Autofac- की

builder.Register<IStartable>().As<StandardConsole>().Singleton(); 
builder.Register<IConsumer<ConsoleCommand>>().As(x => builder.Resolve<IStartable>()); 
+1

के लिए मेरी टिप्पणी देखें कोई नहीं कर सकता।मैं कंपोनेंट एट्रिब्यूट के साथ कक्षाओं के बाद एप्लिकेशन निर्देशिका में सभी असेंबली स्कैन करता हूं और उन्हें लागू करने वाले सभी इंटरफेस के साथ पंजीकृत करता हूं। इससे आपके द्वारा सुझाए गए कार्यों को करना मुश्किल हो जाता है। http://blog.gauffin.org/2010/07/simplified-autofac-registrations/ – jgauffin

2

निकोलस से सुझाव के साथ अपडेट किया गया:

यह इस प्रकार से autofac

private void BuildComponents(ContainerBuilder builder) 
    { 
     string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location); 
     foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
     { 
      if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory)) 
       continue; 

      builder.RegisterAssemblyTypes(assembly) 
       .Where(t => t.IsComponent()) 
       .AsImplementedInterfaces() 
       .SingleInstance(); 
     } 
    } 

    public static bool IsComponent(this Type value) 
    { 
     return value.GetType().GetCustomAttributes(typeof (ComponentAttribute), true).Length > 0; 
    } 
2

में किया है मैं जानता हूँ कि यह एक पुरानी धागा है, लेकिन यहाँ Ninject के लिए समाधान है।

kernel.Bind<StandardConsole>().ToSelf().InSingletonScope(); 
kernel.Bind<IStartable>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>()); 
kernel.Bind<IConsumer<ConsoleCommand>>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>()); 
+0

यह सक्रियण कॉन्टेक्स्ट का उपयोग करते समय काम नहीं करता है। –

+0

@ जेफ: देखें http://www.planetgeek.ch/2011/12/30/new-features-and-changes-of-ninject-3-0/ –

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