2010-11-06 14 views
6

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

उत्तर

0

हम सभी जानते हैं कि यह कई अलग-अलग तरीकों से संभव है, लेकिन कुछ ऐसा जो समझ में आता है, निश्चित रूप से अधिक स्वागत है।मैं कुछ set-only गुण परिभाषित है, तो वस्तु क्या यह करने के लिए पारित हो जाता है के लिए एक संदर्भ के आयोजन के लिए जिम्मेदार है:

public interface IBlogRepository 
{ 
    ISession Session { set; } 
} 

class BlogRepository : IBlogRepository 
{ 
    private ISession m_session; 

    ISession Session 
    { 
     set { m_session = value; } 
    } 
} 

यह हर वर्ग इंटरफेस को लागू करने को पता है कि set-only संपत्ति एक निर्भरता इंजेक्शन है जिस तरह से, जब से set-only गुण हैं बहुत कम प्रयुक्त। मुझे यकीन नहीं है कि इस विधि को good practice के रूप में जाना जाता है या नहीं, लेकिन मेरे लिए यह अब से है।

+0

निर्भरता को परिभाषित करने के केवल एक ही तरीके से कठोर चिपके हुए डिज़ाइन विकल्पों को फेंक रहा है। अन्य विकल्प खराब नहीं हैं, वे सिर्फ अलग हैं। –

+0

इस डिज़ाइन के साथ, आपको गुणों को परिभाषित करने के लिए व्युत्पन्न कक्षाओं की आवश्यकता होती है, लेकिन आपको वर्ग के उपयोगकर्ताओं को निर्भरताओं को भरने की आवश्यकता नहीं है। यदि कोई उपयोगकर्ता आपकी कक्षा को तुरंत चालू करता है, तो उन गुणों को भरता नहीं है, और एक विधि कॉल करता है, तो आप फेंक नहीं सकते हैं। ऐसा करने से इंटरफ़ेस द्वारा परिभाषित अंतर्निहित अनुबंध का उल्लंघन होगा। * आवश्यकता के लिए केवल दो तरीकों * में भरोसा करने की निर्भरता कन्स्ट्रक्टर और विधि पैरामीटर हैं। –

3

एक विकल्प प्रारंभ करने के लिए इंटरफ़ेस पर एक विधि बनाना है। यह विधि सभी आवश्यक निर्भरताओं को स्वीकार कर सकती है।

कुछ की तरह:

void Configure(dependency1 value, etc.); 
बेशक

, वहाँ विकल्पों में से एक बहुत प्रारंभ और इस तरह के DI एक रूपरेखा का उपयोग कर रहे हैं। हालांकि से चुनने के लिए बहुत सारे विकल्प हैं।

स्कॉट हैनसेलमैन की अच्छी सूची here है।

2

आपको क्या करना है, यह है कि आपके सभी इंटरफ़ेस कार्यान्वयन एक कन्स्ट्रक्टर के साथ एक वर्ग को उप-वर्ग में ले जाएं, जो भी राज्य को इंजेक्शन की आवश्यकता है। चूंकि उप-वर्गों को अपने कन्स्ट्रक्टर में बेस-कॉल करने की आवश्यकता होती है, इसलिए आपकी बाधाएं स्वचालित रूप से कायम होती हैं।

पहले इस पर एक अजीब पैटर्न की तरह लग सकता है, लेकिन हम यह हमारे उद्यम समाधान में हर समय का उपयोग करें, तो मैं गारंटी अपने समझदार :-)

7

मैं जानता हूँ कि आप ने कहा आप एक स्थिर अनुबंध करना चाहते हैं। लेकिन एक स्थिर इंटरफेस की आपूर्ति करने के लिए नहीं एक फायदा है कि आपके निर्भरता तो, विभिन्न कार्यान्वयन के साथ बेतहाशा भिन्न हो सकता है जो युग्मन को कम करेगा:

public interface IBlogRepository 
{ 
    IEnumerable<Entry> GetEntries(int pageId, int pageCount); 
} 

class BlogDatabase : IBlogRepository 
{ 
    public BlogDatabase(ISession session) 
    { 
     this.session = session; 
    } 

    public IEnumerable<Entry> GetEntries(int pageId, int pageCount) 
    { 
     // Not that you should implement your queries this way... 
     var query = session.CreateQuery("from BlogEntry"); 
     return query.Skip(pageId * pageCount).Take(pageCount); 
    } 

    private ISession session; 
} 

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

public interface IBlogRepository 
{ 
    ISession Session { get; set; } 
    IEnumerable<Entry> GetEntries(int pageId, int pageCount); 
    IEnumerable<Entry> GetEntriesWithSession(ISession session, 
     int pageId, int pageCount); 
} 

class BlogDatabase : IBlogRepository 
{ 
    public ISession Session { Get; set; } 

    public IEnumerable<Entry> GetEntries(int pageId, int pageCount) 
    { 
     var query = Session.CreateQuery ... 
    } 

    public IEnumerable<Entry> GetEntries(ISession session, int pageId, int pageCount) 
    { 
     var query = session.CreateQuery ... 
    } 
} 

class BlogFile : IBlogRepository 
{ 
    // ISession has to abstract a file handle. We're still okay 
    // ... 
} 

class BlogInMemory : IBlogRepository 
{ 
    // ISession abstracts nothing. 
    // Maybe a lock, at best, but the abstraction is still breaking down 
    // ... 
} 

निर्माता इंजेक्शन केवल काम करेंगे। संपत्ति और तर्क इंजेक्शन ढांचे के बिना भी काम करेगा।

मेरा मानना ​​है कि सभी तीन स्वीकार किए जाते हैं। कम से कम एक लोकप्रिय ढांचे दोनों कन्स्ट्रक्टर और संपत्ति इंजेक्शन का समर्थन करते हैं।

इसका मतलब है कि यह निर्णय आपके ऊपर है कि आपके प्रोजेक्ट के लिए सबसे ज्यादा समझदारी क्या है। व्यापार-बंद एक निर्भरता ग्राफ है जो ट्रेस करना आसान है, मजबूत युग्मन बनाम। निर्णय निश्चित रूप से सभी कन्स्ट्रक्टर या सभी संपत्ति/तर्क होना आवश्यक नहीं है।

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

public interface IInstallationFactory 
{ 
    IUser CreateRegisteredUser(Guid userSid); 
    IPackage CreateKnownPackage(Guid id); 
    IInstaller CreateInstaller(); 
} 

विभिन्न व्यवस्थाएं भी सार कारखानों समर्थन करते हैं।

+1

यह वही है जो मैं कह रहा था, लेकिन इतना बेहतर समझाया गया। +1 और अपना खुद का हटाना। –

0

इंटरफ़ेस निर्भरताओं के लिए ज़िम्मेदार नहीं है। केवल कार्यान्वयन जानता है, अनुबंध को पूरा करने के लिए उसे क्या चाहिए।

डेटाबेस का उपयोग करके एक कार्यान्वयन हो सकता है, दूसरा डेटा को जारी रखने के लिए फ़ाइल सिस्टम का उपयोग कर सकता है।

इंटरफ़ेस घोषित करने की आवश्यकता किस निर्भरता से होनी चाहिए? डेटाबेस प्रबंधक या फाइल सिस्टम प्रबंधक?

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

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