EF 4.1 के साथ जेनेरिक रिपॉजिटरी बिंदु क्या है


145

जैसा कि मैंने DbContext, DbSet और संबंधित इंटरफेस को गहराई से खोदा है, मैं सोच रहा हूं कि आपको इन कार्यान्वयनों के आसपास एक अलग "जेनेरिक" रिपॉजिटरी को लागू करने की आवश्यकता क्यों होगी?

ऐसा लगता है कि DbContext और IDbSet को आपकी ज़रूरत का हर काम करना चाहिए और DbContext के अंदर "Unit of Work" को शामिल करना चाहिए।

क्या मुझे यहां कुछ याद आ रहा है या ऐसा लगता है कि लोग बिना किसी कारण के निर्भरता की एक और परत जोड़ने का आनंद लेते हैं।


यह थोड़ा विवादित / राय आधारित मुद्दा है। मैंने यहां इसकी चर्चा की है
अमित जोशी

जवाबों:


202

आप वास्तव में सही हैं। DbContextकार्य पैटर्न की इकाई का IDbSetकार्यान्वयन है और रिपॉजिटरी पैटर्न का कार्यान्वयन है।

वर्तमान में रिपॉजिटरी बहुत लोकप्रिय हैं और इनका उपयोग किया जाता है। हर कोई उनका उपयोग सिर्फ इसलिए करता है क्योंकि संस्था के ढांचे के लिए भंडार बनाने के बारे में दर्जनों लेख हैं लेकिन कोई भी वास्तव में इस निर्णय से संबंधित चुनौतियों का वर्णन नहीं करता है।

भंडार का उपयोग करने के मुख्य कारण आमतौर पर हैं:

  • ऊपरी परत से ईएफ छिपाएं
  • कोड को बेहतर परीक्षण योग्य बनाएं

पहला कारण कुछ प्रकार की वास्तुशिल्प शुद्धता और महान विचार है कि यदि आप ईएफ पर अपनी ऊपरी परत को स्वतंत्र बनाते हैं तो आप बाद में अन्य दृढ़ता ढांचे पर स्विच कर सकते हैं। वास्तविक दुनिया में आपने ऐसा कितनी बार देखा? यह कारण ईएफ के साथ बहुत कठिन काम करता है क्योंकि आपकी रिपॉजिटरी को कई अतिरिक्त सुविधाओं को उजागर करना चाहिए जो ईएफ को डिफ़ॉल्ट रूप से अनुमति देता है।

एक ही समय में ईएफ कोड लपेटने से आपका कोड बेहतर व्यवस्थित रह सकता है और चिंता नियम के पृथक्करण के बाद। मेरे लिए यह रिपॉजिटरी और काम की इकाई का एकमात्र वास्तविक लाभ हो सकता है लेकिन आपको यह समझना होगा कि ईएफ के साथ इस नियम का पालन करने से शायद आपका कोड बेहतर बनाए रखने योग्य और बेहतर पठनीय हो सकता है लेकिन आपके आवेदन बनाने के शुरुआती प्रयास में बहुत अधिक होगा। छोटे अनुप्रयोगों के लिए यह अनावश्यक जटिलता हो सकती है।

दूसरा कारण आंशिक रूप से सही है। ईएफ का बड़ा नुकसान कठोर वास्तुकला है जिसे शायद ही कभी मॉक किया जा सकता है इसलिए यदि आप इकाई ऊपरी परत का परीक्षण करना चाहते हैं तो आपको ईएफ को किसी भी तरह से लपेटना चाहिए ताकि इसके कार्यान्वयन की अनुमति दी जा सके। लेकिन इसके कई अन्य परिणाम भी हैं जिनका मैंने यहां वर्णन किया है

मैं आयेंडे के ब्लॉग का अनुसरण करता हूं । यदि आपने कभी NHibernate का उपयोग किया है तो आप शायद उसके लेख जानते हैं। इस व्यक्ति ने हाल ही में NHibernate के साथ भंडार का उपयोग करने के खिलाफ कई लेख लिखे, लेकिन NHibernate बहुत बेहतर है।


3
आप IDbSetअपने व्युत्पन्न संदर्भ में कस्टम इंटरफ़ेस को मॉक कर सकते हैं, लेकिन सभी को। एक बार जब आपका कोड ChangeTracker, Entries या कभी भी उपयोग करता है, तो उन सभी को लपेटने के लिए बड़े प्रयास की आवश्यकता होगी।
लादिस्लाव मृका

1
हाँ EF बहुत प्रदर्शन उन्मुख उपकरण नहीं है। कम से कम एमएस के पास भविष्य के संस्करणों में इसे बेहतर बनाने के लिए बहुत सारे अवसर हैं।
लादिस्लाव मृंका

2
@chiccodoro: सही है। लेकिन एक बार जब आपका नकली वर्ग उजागर हो जाता है IQueryableया Expression<>पैरामीटर के रूप में स्वीकार कर लेता है जो आंतरिक रूप से लिनक-टू-एंटिटीज़ क्वेरी के लिए डाल दिया जाता है, तो आप साइड इफेक्ट के साथ नकली घटक के बाहर तर्क को परिभाषित कर रहे हैं जिसे यूनिट परीक्षणों के साथ परीक्षण नहीं किया जा सकता है।
लादिस्लाव मृंका

8
अगर मैं DbSet और BdContext का उपयोग सीधे अपनी व्यावसायिक परत में कर रहा हूं तो मुझे EntityFramework.dll और साथ ही अपने DataLayer प्रोजेक्ट में संदर्भ देना होगा। यह अकेला मुझे बताता है कि इसे किसी प्रकार की लपेट की जरूरत है।
ing Vals

2
डाउनवोट: अधूरा - एक रिपॉजिटरी इंटरफ़ेस के पीछे ईएफ को अमूर्त करने से एसएल और डब्ल्यूपीएफ दोनों में एक ही क्लाइंट कोड चलाया जा सकता है।
h.xx

21

मैं समान मुद्दों से जूझ रहा हूं, और ईएफ परतों की इकाई परीक्षण के लिए नकलीपन महत्वपूर्ण है। लेकिन मैं इस महान लेख पर दौड़ गया, जिसमें बताया गया है कि EF 4.1 DbContext की स्थापना कैसे की जाती है, यह सुनिश्चित करने के लिए कि आपके व्युत्पन्न DbContext ने एक सामान्य इंटरफ़ेस लागू किया है और DbSet के बजाय IDbSet को उजागर किया है। चूँकि मैं डेटाबेस फर्स्ट एप्रोच का उपयोग कर रहा हूँ, क्योंकि हमारा डेटाबेस पहले से ही मौजूद है, मैंने बस अपने व्युत्पन्न DbContext को जेनरेट करने के लिए उपयोग किए गए T4 टेम्प्लेट को संशोधित करके IDbSet इंटरफेस को वापस करने के लिए जेनरेट किया, साथ ही अपने जेनेरिक इंटरफ़ेस से प्राप्त किया। इस तरह से पूरी चीज़ को आसानी से मज़ाक किया जा सकता है, और आपको अपनी स्वयं की यूनिट ऑफ़ वर्क या रिपॉजिटरी पैटर्न को लागू करने की आवश्यकता नहीं है। अपने सामान्य इंटरफ़ेस का उपभोग करने के लिए बस अपना सेवा कोड लिखें, और जब आप इकाई परीक्षण में जाएं,

http://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with-a-generic-repository/


5

रिपॉजिटरी बनाने का एक कारण यह है कि आप DBSet और DbContext के कार्यान्वयन को छिपा सकते हैं यदि आप EntityFramework से किसी अन्य चीज़ पर जाने का निर्णय लेते हैं या इसके विपरीत।

उदाहरण के लिए, मैं NHibernate का उपयोग कर रहा था और मैंने अपने रिपॉजिटरी कक्षाओं के अंदर सभी कॉल को उस फ्रेमवर्क में लपेट दिया। वे IEnumerable को अपने "सामान्य" होने के लिए वापस कर देते हैं और मेरे रिपॉजिटरी में मानक CRUD ऑपरेशन (अपडेट, डिलीट, आदि) हैं। मैं लंबे समय से एंटिटी फ्रेमवर्क में स्थानांतरित हुआ हूं। ऐसा करने पर, मुझे अपने ViewModel कक्षाओं में या उससे आगे कुछ भी बदलने की आवश्यकता नहीं थी क्योंकि उन्होंने मेरी रिपॉजिटरी की ओर इशारा किया था - मुझे केवल अपने रिपॉजिटरी के अंदर बदलने की आवश्यकता थी। इससे प्रवास के दौरान जीवन बहुत आसान हो गया।

(मैंने NHibernate का उपयोग किया क्योंकि हम ISeries से जुड़ रहे हैं, और उस समय, ISF के साथ EF का उपयोग करके कोई भी लागत प्रभावी कार्यान्वयन नहीं थे। केवल एक ही उपलब्ध आईबीएम को उनके DB2Connect के लिए $ 12,000 का भुगतान करना था)


"लगभग" (DBSet और DbContext को छिपाने के विषय पर) आप पाएंगे कि आपको किसी भी उपभोक्ता को EF को उजागर करने की आवश्यकता नहीं है (उदाहरण के लिए यदि आप DI का लाभ उठाते हैं) लेकिन आपको IDbet <T> गुण को उजागर करने वाले इंटरफ़ेस की आवश्यकता है एक कदम आगे बढ़ें और इसके बजाय अपने सभी गुणों को IQueryable <T> के रूप में लिखें, लेकिन मेरा कहना यह है कि आप DbSet और DbContext पर अपनी निर्भरता को पूरी तरह से छिपा सकते हैं। CRUD ऑप्स को फिर विस्तार विधियों के रूप में लिखा जा सकता है, आप विभिन्न बैकिंग स्टोर्स के लिए कई एक्सटेंशन तरीके लिख सकते हैं। हालांकि, आप LINQ के उपयोग को नहीं छिपाएंगे।
शॉन विल्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.