2012-01-06 2 views
18

में फ़ंक का उपयोग करके एकाधिक आईडीबीकनेक्शन फ़ैक्टरी उदाहरणों को कैसे पंजीकृत करें, आप फ़ंक में अलग-अलग IDbConnectionFactory उदाहरणों को पंजीकृत करने के बारे में कैसे जाएंगे और फिर उन्हें सीधे अपनी सेवाओं के भीतर एक्सेस करेंगे? नामित उदाहरण किसी भी तरह यहां खेलने में आते हैं?सर्विसस्टैक.net

क्या यह सेवाओं में विभिन्न डेटाबेस का उपयोग करते समय लेने का सबसे अच्छा तरीका है?

धन्यवाद!

संपादित करें:

एक उदाहरण;)। मैं यहां से रास्ता निकाल सकता हूं क्योंकि मैं आईओसी के लिए काफी नया हूं, लेकिन उदाहरण के लिए कहें कि मेरे पास 2 अलग डेटाबेस कनेक्शन हैं जिन्हें मैं इंजेक्ट करना चाहता हूं। ServiceStack में, यह Global.asax में किया जाता है।

container.Register<IDbConnectionFactory>(c => 
      new OrmLiteConnectionFactory(@"Connection String 1", SqlServerOrmLiteDialectProvider.Instance));            

container.Register<IDbConnectionFactory>(c => 
      new OrmLiteConnectionFactory(@"Connection String 2", SqlServerOrmLiteDialectProvider.Instance));     

इन दोनों को सम्मानित डोरी इंजेक्शन लगते हैं।

ये तो कुछ इस तरह के माध्यम से सेवा समाप्ति पर स्वचालित रूप से पहुंचा जा सकता है:

public IDbConnectionFactory DbFactory { get; set; } 

इस मामले में, यह मुझे दे करने के लिए पहले एक पंजीकृत लगता है। मैं सेवा अंत में किसी विशिष्ट व्यक्ति तक पहुंच कैसे प्राप्त कर सकता हूं? उम्मीद है कि यह थोड़ा और स्पष्ट बनाता है।

यहाँ ServiceStack.Examples है कि केवल 1 IDbConnectionFactory का उपयोग करता है से एक पूर्ण विकसित उदाहरण है: Movies Rest

+0

क्या आप कुछ कोड दिखा सकते हैं? मुझे लगता है कि हम आपको अपने आवेदन के डिजाइन पर कुछ सुझाव दे सकते हैं, लेकिन इसके लिए, हमें वास्तविक डिजाइन की अधिक अंतर्दृष्टि की आवश्यकता है। यह देखना दिलचस्प होगा कि आप उन 'आईडीबीकनेक्शन फैक्ट्री' के इरादे से इंजेक्ट करते हैं, और उन सेवाओं को 'आईडीबीकनेक्शन फैक्ट्री' निर्भरताओं के साथ क्या करना है। – Steven

+0

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

+0

मैंने प्रश्न को अद्यतन किया, इसे थोड़ा और स्पष्ट कर दिया और सरल इंजेक्टर पर आपका आलेख पाया। मैं आईओसी की समझ को गहरा बनाने की उम्मीद में अब पढ़ रहा हूं। –

उत्तर

14

ऊपर मेरा प्रश्न अभी भी मान्य है, लेकिन निम्न वैसे भी आपकी मदद कर सकता है।

फ़ंक स्वचालित कन्स्ट्रक्टर इंजेक्शन (ए.के.ए. ऑटो वायरिंग) का समर्थन नहीं करता है, और आपको इसे Func<T> लैम्ब्डा अभिव्यक्तियों का निर्माण करके हाथ से करना होगा। चूंकि आप हाथ से कन्स्ट्रक्टर इंजेक्शन कर रहे हैं, इसलिए यह चुनना आसान है कि IDbConnectionFactory क्या आप अपनी सेवाओं में इंजेक्ट करना चाहते हैं। उदाहरण:

IDbConnectionFactory yellowDbConFactory = 
    new YellowDbConnectionFactory(); 

IDbConnectionFactory blueDbConFactory = 
    new BlueDbConnectionFactory(); 

IDbConnectionFactory purpleDbConFactory = 
    new PurpleDbConnectionFactory(); 

container.Register<IService1>(c => 
    new Service1Impl(yellowDbConFactory, 
     c.Resolve<IDep1>()); 

container.Register<IService2>(c => 
    new Service2Impl(blueDbConFactory); 

container.Register<IService3>(c => 
    new Service3Impl(purpleDbConFactory, 
     c.Resolve<IDep2>()); 
बेशक

आप भी नामित इस्तेमाल कर सकते हैं पंजीकरण, इस तरह:

container.Register<IDbConnectionFactory>("yellow", 
    new YellowDbConnectionFactory()); 

container.Register<IDbConnectionFactory>("blue", 
    new BlueDbConnectionFactory()); 

container.Register<IDbConnectionFactory>("purple", 
    new PurpleDbConnectionFactory()); 

container.Register<IService1>(c => 
    new Service1Impl(
     c.Resolve<IDbConnectionFactory>("yellow"), 
     c.Resolve<IDep1>()); 

container.Register<IService2>(c => 
    new Service2Impl(
     c.Resolve<IDbConnectionFactory>("blue")); 

container.Register<IService3>(c => 
    new Service3Impl(
     c.Resolve<IDbConnectionFactory>("purple"), 
     c.Resolve<IDep2>()); 
ऑटो तारों के लिए समर्थन की कमी की वजह से

, तो आप इन बल्कि अजीब पंजीकरण के साथ खत्म होगा, और यह जल्द ही आपके रचनात्मक रूट के रखरखाव दुःस्वप्न में परिणाम देगा, लेकिन यह आपके प्रश्न से संबंधित नहीं है ;-)

आपको आमतौर पर अपने पंजीकरण में अस्पष्टता को रोकने की कोशिश करनी चाहिए। आपके मामले में आपके पास एक इंटरफ़ेस है, जो दो चीजें करता है (दो डेटाबेस से कनेक्ट होता है)।जब तक दोनों डेटाबेस में ठीक उसी मॉडल का हिस्सा, प्रत्येक डेटाबेस का अपना इंटरफ़ेस हकदार (यदि दो कार्यान्वयन विनिमेय नहीं हैं, आप Liskov substitution principle का उल्लंघन हो जाएगा):

interface IYellowDbConnectionFactory : IDbConnectionFactory 
{ 
} 

interface IPurpleDbConnectionFactory : IDbConnectionFactory 
{ 
} 
जिस तरह से काम करता है के ServiceStack

, तो आप शायद जरूरत

class YellowDbConnectionFactory : OrmLiteConnectionFactory, 
    IYellowDbConnectionFactory 
{ 
    public YellowDbConnectionFactory(string s) : base(s){} 
} 

class PurpleDbConnectionFactory : OrmLiteConnectionFactory, 
    IPurpleDbConnectionFactory 
{ 
    public YellowDbConnectionFactory(string s) : base(s){} 
} 

अब आप के बजाय IDbConnectionFactory का उपयोग करने का विशिष्ट इंटरफेस का उपयोग करने अपनी सेवाओं की परिभाषा बदलना चाहिए:

public class MovieService : RestServiceBase<Movie> 
{ 
    private readonly IYellowDbConnectionFactory dbFactory; 

    public MovieService(IYellowDbConnectionFactory factory) 
    { 
     this.dbFactory = factory; 
    } 
} 
प्रत्येक के लिए एक कार्यान्वयन लागू करने के लिए

ध्यान दें कि यह कक्षा अब संपत्ति इंजेक्शन के बजाय कन्स्ट्रक्टर इंजेक्शन का उपयोग करती है। आप इसे संपत्ति इंजेक्शन के साथ काम करने के लिए प्राप्त कर सकते हैं, लेकिन आमतौर पर कन्स्ट्रक्टर इंजेक्शन के साथ जाना बेहतर होता है। इसके बारे में SO question यहां है। , MovieService को

container.Register<MovieService>(c => 
    new MovieService(
     c.Resolve<IYellowDbConnectionFactory>()); 

उन दो नए इंटरफेस और दो वर्गों और परिवर्तन आप एक बहुत जीत नहीं पाए क्योंकि Funq ऑटो का समर्थन नहीं करता:

Funq साथ

, आपके विन्यास तो इस तरह दिखेगा तारों। आप वह व्यक्ति होंगे जो मैन्युअल रूप से सबकुछ तारों से तार रखता है। हालांकि, जब आप एक फ्रेमवर्क पर स्विच करते हैं जो ऑटो-वायरिंग का समर्थन करता है, तो यह डिज़ाइन कंटेनर को बिना किसी समस्या के सही निर्भरताओं को इंजेक्ट करने की अनुमति देता है, क्योंकि इंजेक्ट करने के बारे में कोई चर्चा नहीं है।

+1

पूरी तरह से जवाब के लिए धन्यवाद। यह वही है जो मैं खोज रहा था। –

+5

नोट: सर्विसस्टैक वास्तव में अपने Funq.Container के साथ ऑटो तारों का समर्थन करता है - मेरा जवाब देखें। – mythz

+1

@Steven क्या होगा यदि डेटाबेस समान मॉडल साझा करते हैं? यानी मल्टी किरायेदार –

11

हालांकि फ़ंक ऑटो वायरिंग का समर्थन नहीं करता है, ServiceStack इसके कार्यान्वयन करता है। ServiceStack के नवीनतम संस्करण Funq.Container भार के शामिल हैं:

container.RegisterAutoWired<T>(); 
container.RegisterAutoWiredAs<T,TAs>(); 
container.RegisterAs<T,TAs>(); 

तो स्टीवन के उदाहरण में आप भी कर सकते हैं:

container.RegisterAs<YellowDbConnectionFactory,IYellowDbConnectionFactory>(); 

और यह आपके लिए अपने आप निर्भरता रजिस्टर करेंगे।

+0

ऐसी सुविधा रखने के लिए एक सेवा फ्रेमवर्क कार्यान्वयन के लिए काफी अजीब है। यह एक आईओसी कंटेनर के लिए एक सुविधा की तरह लगता है, न कि सर्विसस्टैक के लिए। – Steven

+1

सहमत हुए, मैंने इसे बहुत समय पहले फंक की मेलिंग सूची में पोस्ट किया था लेकिन इसमें कुछ भी नहीं आया था http://funq.codeplex.com/workitem/2158 – mythz

+2

फ़ंक फ्रेमवर्क पहले से ही लंबे समय से त्याग दिया प्रतीत होता है। सर्विसस्टैक के लिए डिफ़ॉल्ट आईओसी फ्रेमवर्क के रूप में आप सरल इंजेक्टर पर क्यों नहीं जाते? चूंकि सर्विसस्टैक एक उच्च प्रदर्शन ढांचा प्रतीत होता है, इसलिए सरल इंजेक्टर एक अच्छा फिट है, क्योंकि यह क्षेत्र में सबसे तेज़ आईओसी ढांचा है। मुझे लगता है कि सर्विसस्टैक वास्तव में अच्छा है, बीटीडब्ल्यू। – Steven

1

इस आईओसी के बजाय रिपोजिटरी पैटर्न का उपयोग करने का प्रयास करें (जो केवल अनावश्यक चीज़ों को जटिल करता है)। उपरोक्त कोड काम नहीं करता है। संदेह कुछ बदल गया है। मैं अभी भी अस्पष्ट हूं कि आईडीबीकनेक्शन को कैसे पंजीकृत किया जा रहा है फैक्ट्री जादुई रूप से IDbConnection प्रॉपर्टी को पॉप्युलेट करता है। इसके चारों ओर कुछ स्पष्टीकरण पसंद करेंगे। अगर किसी को कभी भी सर्विसस्टैक आईओसी कंटेनर का उपयोग करके यह काम मिल जाता है .. तो मुझे यह देखना अच्छा लगेगा कि कैसे। और एसएस दस्तावेज़ों को अपडेट करने के लिए यह बेहद फायदेमंद होगा (मुझे यह करने में काफी खुशी है)

+0

IDbConnectionFactory के संबंध में, आप सर्विसस्टैक OrmLite कोड का संदर्भ ले सकते हैं: सार्वजनिक आभासी IDbConnection डीबी {get {return this.db ?? (this.db = OrmLiteConnectionFactoryExtensions.Open (यह.TryResolve ())); }} – labilbe

3

सोचा कि मैं अपने 2 सेंट में चिपकूँगा, हालांकि मुझे एहसास है कि सवाल बहुत पुराना है। मैं एक लेन-देन संबंधी DB और ServiceStack से एक प्रवेश DB का उपयोग करना चाहते थे और यह कैसे मैं() AppHostBase विन्यस्त से यह कर विधि समाप्त हो गया है:

  container.Register<IDbConnectionFactory>(
       c => { 
        OrmLiteConnectionFactory dbFactory = new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["MyTransactionalDB"].ConnectionString, MySqlDialect.Provider); 
        dbFactory.ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current); 
        dbFactory.RegisterConnection("LoggingDB", ConfigurationManager.ConnectionStrings["MyLoggingDB"].ConnectionString, MySqlDialect.Provider); 

        return dbFactory; 
       }); 

डिफ़ॉल्ट रूप से, "MyTransactionalDB" जब एक कनेक्शन खोलने प्रयोग किया जाता है कारखाने से, लेकिन मैं स्पष्ट रूप से लॉगिंग डीबी को किसी सेवा से एक्सेस कर सकता हूं:

 using (var db = DbFactory.Open("LoggingDB")) 
     { 
      db.Save(...); 
     }