2013-05-06 8 views
13

फिलहाल मैं एकता के साथ निर्भरता इंजेक्शन कंटेनर के साथ थोड़ा सा प्रयोग कर रहा हूं।निर्भरता इंजेक्शन और अन्य कन्स्ट्रक्टर पैरामीटर - खराब अभ्यास?

को देखते हुए निम्नलिखित इंटरफ़ेस:

public interface IPodcastCommService 
{ 
    void Download(); 

    void Upload(); 
} 

और निम्नलिखित कार्यान्वयन:

public class PodcastService 
{ 
    private IPodcastCommService commservice; 
    private String url; 

    public PodcastService(String url, IPodcastCommService commservice) 
    { 
     this.commservice = commservice; 
     this.url = url; 
    } 
} 
निर्माता की वजह से

, मैं यह करने के लिए पैरामीटर पारित करने के लिए एक समाधान के लिए देख रहा था और पाया यह:

var p = container.Resolve<IPodcastCommService>(new ParameterOverride("url", myUrl)); 

अब तक इतना अच्छा है, लेकिन साथ ही मैंने पढ़ा है कि यह कितना बुरा है और कैसे कक्षा का डिज़ाइन खराब है और हां, यह थोड़ा बदसूरत दिखता है। लेकिन मैं एक सुरुचिपूर्ण तरीके से कक्षा में पैरामीटर कैसे पारित कर सकता हूं?

मेरा पहला विचार यह संपत्ति के रूप में करना था, लेकिन फिर मुझे हर बार जांच करना होगा कि मुझे पहले से ही यूआरएल की आवश्यकता है।

अद्यतन:

लेकिन वहाँ मामलों आप संकल्प ऑपरेशन के लिए कस्टम निर्माता मानकों में पारित किया है जहां हो सकता है: एक उदाहरण है, मैं जहां पढ़ा है कि यह बुरा डिजाइन है, यह है। कुछ लोग तर्क दे सकते हैं कि यह खराब वास्तुकला की चिल्लाती है लेकिन ऐसी स्थितियां हैं जैसे डीआई कंटेनर को विरासत प्रणाली में लाने के लिए जो इस तरह के कार्यों की आवश्यकता हो सकती है।

स्रोत: http://mikaelkoskinen.net/unity-passing-constructor-parameters-to-resolve/

+1

क्या आप मुझे यह बताना चाहते हैं कि आपके पास लाल रंग है जहां यह खराब डिजाइन है? क्योंकि मैं वास्तव में सोचता हूं कि यह डिज़ाइन सबसे अच्छा है जिसे आप कभी भी प्राप्त करेंगे। – Egi

+0

@Egi: मैंने एक स्रोत के साथ अपना प्रश्न अपडेट किया। – Kai

+0

आप कन्स्ट्रक्टर में इंजेक्शन गुणों को सूचीबद्ध किए बिना DI को करने के लिए [ServiceLocator] (https://commonservicelocator.codeplex.com/) का उपयोग कर सकते हैं। – orad

उत्तर

3

मुझे यह नहीं मिलता है कि IPodcastCommService को लागू करने के बजाय आपको IPodcastCommService की रचना के साथ पॉडकास्ट सेवा की आवश्यकता क्यों है और स्ट्रिंग द्वारा यूआरएल इंजेक्शन दिया गया है। मुझे समझ में नहीं आता कि आपका डिजाइन खराब क्यों है। यूआरएल इंजेक्शन अच्छा IMHO है।

यदि आप बेहतर तरीके से सोचते हैं, तो मुझे लगता है कि इसे देशी डेटा प्रकार के बजाय संदर्भ/कॉन्फ़िगरेशन इंजेक्शन द्वारा प्रतिस्थापित किया जा सकता है।

public class PodcastService 
{ 
    private IPodcastCommService commservice; 
    private IConnectionContext connection; 

    public PodcastService(IConnectionContext connection, IPodcastCommService commservice) 
    { 
     this.commservice = commservice; 
     this.connection= connection; 
    } 
} 

public interface IConnectionContext{ 
    string PodcastServiceUrl{get;} 
} 

लेकिन फिर से, मैं (छोड़कर आप सत्र/स्थिरांक/स्थिर क्षेत्रों संभाल कर सकते हैं) नियमित दृष्टिकोण से यह से कोई लाभ नहीं मिल रहा है।

अद्यतन:

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

-3

यह ढांचा यू का उपयोग कर रहे पर निर्भर करता है। उदाहरण के लिए आईपीसी कंटेनर जैसे DependecyResolver के लिए एएसपीएनटी एमवीसी प्रदाताओं एकीकरण बिंदु। वस्तुओं को बनाने और निर्भरताओं को इंजेक्शन देने के लिए आपको अपना सभी तर्क रखना चाहिए। यदि आप aps.net का उपयोग कर रहे हैं तो आपके पास कुछ प्रकार का बेस पेज हो सकता है जो preinit eevnt इंजेक्ट्स निर्भरता का है। आप एएसपीनेट, केवल संपत्ति इंजेक्शन के साथ कन्स्ट्रक्टर इंजेक्शन का उपयोग नहीं कर सकते हैं। Winforms के साथ आप फॉर्म ऑब्जेक्ट्स बनाने के लिए किसी प्रकार के फॉर्म फैक्ट्री का उपयोग कर सकते हैं।

1

आपके परिदृश्य में मुझे लगता है कि निर्माता के माध्यम से DI पूरी तरह से ठीक है। गुणों के माध्यम से जाने के लिए इसे बेहतर दृष्टिकोण माना जाता है क्योंकि यह पठनीयता के लिए बेहतर है यानी कल्पना करें कि आपका कन्स्ट्रक्टर कैसा दिखता है यदि आपको 20 गुणों को इंजेक्ट करना था।

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

+2

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

+2

यदि आपके कन्स्ट्रक्टर के पास 20 तर्क हैं, तो मैं शर्त लगाता हूं कि आपकी कक्षा एसआरपी को आवाज़ देती है और बेहतर पठनीयता के लिए संपत्ति इंजेक्शन का दुरुपयोग करने के बजाय छोटे वर्गों में दोबारा प्रतिक्रिया दी जानी चाहिए! मेरी राय में संपत्ति इंजेक्शन अच्छा है यदि आपको गतिशील व्यवहार की आवश्यकता है जो रनटाइम के दौरान बदलना चाहिए। – Egi

1

हो सकता है कि एक

container.RegisterType<PodcastService>(new InjectionConstructor("myUrlParameter")); 

बेहतर करना होगा, ऐसा नहीं है?

लेकिन यदि आपको एक पॉडकास्ट सेवा की आवश्यकता है और उन्हें एक और यूआरएल चाहिए, तो पैरामीटर ओवरराइड ठीक है।

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