2012-03-15 13 views
8

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

public class Foo 
{ 
    private List<Bar> _bars; 
    private BarFactory _barFactory; 

    ... 

    public void MakeBar() 
    { 
     _bars.Add(_barFactory.MakeBar()); 
    } 
} 

यहाँ बार, जो जब _barFactory.MakeBar() कहा जाता हो जाता है बना दिया जाता है:

मैं एक वर्ग फू कहा जाता है, जो बार्स की एक सूची है, और एक कारखाने के माध्यम से उन्हें बनाता है, इस तरह की है कहो। मैं बार serializable होना चाहते हैं:

public class Bar : ISerializable 
{ 
    private List<IPickle> _pickles; 
    private PickleFactory _pickleFactory; 

    public Bar(PickleFactory factory) 
    { 
     _pickleFactory = factory; 
    } 

    public void MakePickle(int x) 
    { 
     _pickles.Add(_pickleFactory.MakePickle(x)); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     //serialize member variables here 
    } 

    //Constructor called during deserialization 
    private Bar(SerializationInfo info, StreamingContext context) 
    { 
     //fill in member variables with data from SerializationInfo 
    } 
} 

सूचना है कि बार अपनी ही कारखाने और अचार का एक संग्रह है। यहां समस्या है: जब बार के deserialization कन्स्ट्रक्टर बुलाया जाता है, तो मेरे पास इसे एक और PickleFactory पाने का कोई तरीका नहीं है। मूल PickleFactory BarFactory द्वारा बार को दिया गया था, लेकिन deserialization कन्स्ट्रक्टर BarFactory द्वारा नहीं कहा गया था।

इस समस्या को हल करने की मेरी वर्तमान योजना बार के सभी धारावाहिक सदस्यों को बारडाटा ऑब्जेक्ट नामक अपनी कक्षा में निकालना होगा। तब मैं BarDataObject serializable बनाऊंगा, लेकिन बार खुद नहीं। मैं BarFactory में एक फ़ंक्शन जोड़ूंगा जो पैराडाटा ऑब्जेक्ट को पैरामीटर के रूप में स्वीकार करता है और बारडाटा ऑब्जेक्ट से सभी जानकारी के साथ भरने के लिए एक बार बनाता है।

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

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

+0

क्या आप अपनी 'बारफैक्टरी' कक्षा में एक कन्स्ट्रक्टर जोड़ सकते हैं जो क्रमबद्धता जानकारी स्वीकार करता है? – Matthew

+3

फू का किस प्रकार का ऑब्जेक्ट है? क्या यह एक 'नया' या 'इंजेक्शन योग्य' है? (Http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/)। –

+0

@ मैथ्यू - अगर मैंने किया, तो मुझे कारखाने में SerializationInfo कैसे मिलेगा? उस समय तक बार के निजी कन्स्ट्रक्टर को बुलाया गया है, कारखाने से बार बनाने के लिए बहुत देर हो चुकी है, क्योंकि हम पहले ही बार कन्स्ट्रक्टर में हैं, और बार किसी भी मामले में बारफैक्टरी के बारे में नहीं जानते हैं। – tandersen

उत्तर

9

मेरे अनुभव में, केवल सेवा वर्गों में निर्भरता होनी चाहिए, और सेवा कक्षाओं को क्रमिकरण के अधीन कभी नहीं होना चाहिए।

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

यह बताने के लिए आप वास्तव में क्या Bar साथ पूरा करने के लिए कोशिश कर रहे हैं मुश्किल है, लेकिन मैं क्या देख सकते हैं, मैं Pickle एक POCO हो रही है, और एक कस्टम Bar वर्ग के बजाय एक List<Pickle> उपयोग करने का सुझाव चाहते हैं।

या, Bar अन्य serializable जानकारी एक अचार संपत्ति के साथ एक POCO, अचार के अलावा है Bar बनाने के लिए करना है, तो:

public class Bar 
{ 
    public string Name {get;set;} 
    public List<Pickle> Pickles {get;set;} 
} 

क्योंकि Pocos निर्भरता की जरूरत नहीं होगी, वे कारखानों आवश्यकता नहीं होनी चाहिए, तो यह वर्ग पूरी तरह से serializable होना चाहिए। यदि जटिल कार्य हैं जिन्हें आप Bar एस और Pickle एस पर निष्पादित करना चाहते हैं, तो उन्हें अलग-अलग उपयोगिता सेवाओं में शामिल किया जाना चाहिए जो Bar s और Pickle एस को उनके विधि पैरामीटर के रूप में लेते हैं।

+0

मैं स्ट्रिपिंगवायरियर से सहमत हूं: आपको डेटा और व्यवहार को अलग करना चाहिए। – Steven

+0

उत्तर के लिए धन्यवाद, ऐसा लगता है कि यह मेरी तत्काल समस्या के लिए काम कर सकता है। असल में, आप सुझाव दे रहे हैं कि मैं बार और पिकल से सभी सेवाओं को लेता हूं, और फ़ू उन सेवाओं (जैसे कारखानों) के बजाय बात करता हूं? ठीक। लेकिन क्या होगा अगर बाद में मुझे फू को क्रमबद्ध करने की भी आवश्यकता है? क्या मैं फू को एक पीओसीओ भी बना सकता हूं, और फूओ, बार्स और पिकल्स के लिए सभी सेवाओं को उस व्यक्ति में ले जाता हूं जिसने फू बनाया है? क्या वह अंततः एक बड़ी बदसूरत कक्षा में नतीजा नहीं दे रहा है जिसकी कई जिम्मेदारियां हैं? – tandersen

+1

@tandersen: ऐसा लगता है जैसे आप सिद्धांत को समझते हैं। लेख मार्क सीमन में उनकी टिप्पणी में शामिल एक ही रणनीति है। (मार्क ने सचमुच DI पर पुस्तक को .NET में लिखा था)। मुझे लगता है कि यदि आप इस पैटर्न का पालन करते हैं तो आपको जिम्मेदारियों को अलग करना और कक्षा के आकार को छोटा रखना बहुत आसान लगेगा। यदि नहीं, तो एक नया प्रश्न पोस्ट करने के लिए स्वतंत्र महसूस करें और देखें कि एसओ समुदाय आपके विशेष मामले के लिए कुछ उपयोगी पैटर्न बता सकता है या नहीं। – StriplingWarrior

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