एन-टियर एंटिटी फ्रेमवर्क समाधान के साथ निर्भरता इंजेक्शन


12

मैं वर्तमान में एक एन-टियर समाधान डिजाइन कर रहा हूं जो एंटिटी फ्रेमवर्क 5 (.net 4) का उपयोग अपनी डेटा एक्सेस रणनीति के रूप में कर रहा है, लेकिन यह परीक्षण योग्य / लचीला बनाने के लिए निर्भरता इंजेक्शन को शामिल करने के तरीके के बारे में चिंतित है।

मेरा वर्तमान समाधान लेआउट निम्नानुसार है (मेरे समाधान को अलकाट्राज़ कहा जाता है):

Alcatraz.WebUI : एक asp.net वेबफॉर्म प्रोजेक्ट, फ्रंट एंड यूजर इंटरफेस, प्रोजेक्ट्स Alcatraz.Business और Alcatraz.Data.Models

Alcatraz.Business : एक क्लास लाइब्रेरी प्रोजेक्ट, जिसमें व्यावसायिक तर्क होते हैं, संदर्भ प्रोजेक्ट Alcatraz.Data.Access , Alcatraz.Data.Models

Alcatraz.Data.Access : एक वर्ग पुस्तकालय परियोजना, मकान AlcatrazModel.edmx और AlcatrazEntitiesDbContext, संदर्भ परियोजना Alcatraz.Data.Models

Alcatraz.Data.Models : एक क्लास लाइब्रेरी प्रोजेक्ट में, Alcatraz मॉडल के लिए POCO शामिल हैं, कोई संदर्भ नहीं।

यह समाधान कैसे काम करेगा, इसके लिए मेरी दृष्टि वेब-यूआई व्यापार पुस्तकालय के भीतर एक भंडार को तुरंत रोक देगी, इस भंडार में कनेक्शन स्ट्रिंग (कोई AlcatrazEntitiesउदाहरण नहीं) की निर्भरता (निर्माणकर्ता के माध्यम से ) होगी। वेब-यूआई डेटाबेस कनेक्शन स्ट्रिंग्स को जानता होगा, लेकिन ऐसा नहीं है कि यह एक इकाई फ्रेमवर्क कनेक्शन स्ट्रिंग था।

व्यवसाय परियोजना में:

public class InmateRepository : IInmateRepository
{
    private string _connectionString;

    public InmateRepository(string connectionString)
    {
        if (connectionString == null)
        {
            throw new ArgumentNullException("connectionString");
        }

        EntityConnectionStringBuilder connectionBuilder = new EntityConnectionStringBuilder();

        connectionBuilder.Metadata = "res://*/AlcatrazModel.csdl|res://*/AlcatrazModel.ssdl|res://*/AlcatrazModel.msl";
        connectionBuilder.Provider = "System.Data.SqlClient";
        connectionBuilder.ProviderConnectionString = connectionString;

        _connectionString = connectionBuilder.ToString();
    }

    public IQueryable<Inmate> GetAllInmates()
    {
        AlcatrazEntities ents = new AlcatrazEntities(_connectionString);

        return ents.Inmates;
    }
}

वेब UI में:

IInmateRepository inmateRepo = new InmateRepository(@"data source=MATTHEW-PC\SQLEXPRESS;initial catalog=Alcatraz;integrated security=True;");

List<Inmate> deathRowInmates = inmateRepo.GetAllInmates().Where(i => i.OnDeathRow).ToList();

इस डिजाइन के बारे में मेरे कुछ संबंधित प्रश्न हैं।

  1. क्या यह डिज़ाइन एंटिटी फ्रेमवर्क क्षमताओं के संदर्भ में भी समझ में आता है? मैंने सुना है कि इकाई ढांचा पहले से ही यूनिट-ऑफ-वर्क के पैटर्न का उपयोग करता है, क्या मैं सिर्फ अमूर्त की एक और परत जोड़ रहा हूं?

  2. मैं नहीं चाहता कि मेरा वेब-यूआई सीधे एंटिटी फ्रेमवर्क के साथ संवाद करे (या उस मामले के लिए भी इसे संदर्भित करें), मैं चाहता हूं कि सभी डेटाबेस तक व्यावसायिक परत के माध्यम से जाया जाए क्योंकि भविष्य में मेरे पास एक ही व्यवसाय परत का उपयोग करके कई परियोजनाएं होंगी (वेब सेवा, विंडोज़ अनुप्रयोग, आदि) और मैं एक केंद्रीय क्षेत्र में व्यावसायिक तर्क रखने के द्वारा इसे बनाए रखना / अपडेट करना आसान बनाना चाहता हूं। क्या यह इसे प्राप्त करने का एक उचित तरीका है?

  3. क्या व्यावसायिक परत में भी रिपॉजिटरी होनी चाहिए, या जो एक्सेस लेयर के भीतर होनी चाहिए? यदि वे कहाँ ठीक हैं, तो क्या कनेक्शन स्ट्रिंग एक अच्छी निर्भरता मान रहा है?

पढ़ने के लिए समय निकालने के लिए धन्यवाद!

जवाबों:


11

जिस तरह से आप डीआई कर रहे हैं वह गलत है।

सबसे पहले, कनेक्शन स्ट्रिंग डेटा परत में है। या web.config फ़ाइल में।

आप के साथ काम करने वाले अगले अमूर्त DbContext होगा, कनेक्शन स्ट्रिंग नहीं। आपके रिपॉजिटरी को कनेक्शन स्ट्रिंग्स के बारे में पता नहीं होना चाहिए। आपके व्यावसायिक तर्क DbContext आदि के बारे में नहीं जानते होंगे।

आपके UI का कोई विचार नहीं होगा और EF से संबंधित किसी भी चीज़ को तुरंत नहीं करेगा।

आपकी बातों के ठोस जवाब:

  1. सार को न जोड़ें, जब तक कि आप ईएफ से बहुत परिचित नहीं हैं। यह पहले से ही यूओडब्ल्यू जैसे अच्छे सार, प्रश्न, पीओसीओ का उपयोग करके आदि जोड़ता है।

  2. DI को काम करने के लिए, आपके पास एक रचना रूट है जो आवश्यक सभी घटकों को संदर्भित करता है। यह WebUI प्रोजेक्ट में हो भी सकता है और नहीं भी। यदि ऐसा नहीं है, तो आपको उम्मीद करनी चाहिए कि यह ईएफ या किसी अन्य डेटा से संबंधित तकनीक का संदर्भ नहीं देता है।

  3. यहीं रुक जाओ। अमूर्तता पर अमूर्त जोड़ना बंद करो। प्रत्यक्ष और 'भोले' वास्तुकला के साथ शुरू करें और समय के साथ इसे विकसित करें।

सार जटिलता से निपटने के लिए एक उपकरण है। जटिलता की अनुपस्थिति का अर्थ है (अभी तक) आवश्यक किसी भी सार को नहीं।


यह स्पष्ट करने के लिए कि मैं समझता हूं कि आप क्या कह रहे हैं: रिपॉजिटरी (जो इंटरफ़ेस व्यवसाय में मौजूद है, और अलकाट्राज़ में डेटा मौजूद है। डेटा। असफल) DbContextइसकी निर्भरता के रूप में स्वीकार करता है । व्यापारिक वर्गों के पास एक निर्भरता के रूप में भंडार हैं। निर्भरता इंजेक्शन के लिए, मैं इसे मैन्युअल रूप से कर रहा हूं (इसलिए मैं समझता हूं कि क्या चल रहा है)। जिस कारण से मैं कनेक्शन स्ट्रिंग को सेट करने में सक्षम होना चाहता हूं, DbContextक्या मैं डेटाबेस का उपयोग कर रहा हूं ताकि कुछ मामलों में मुझे अलग-अलग डेटाबेस (एक ही संरचना) से जुड़ने के लिए इकाई ढांचे की आवश्यकता हो। क्या मैं आपको ठीक से समझ पा रहा हूं?
मैथ्यू

आपके द्वारा प्रदान किए गए कोड से, ऐसा लगता है कि आप DI बिल्कुल नहीं कर रहे हैं। DI का मुख्य उद्देश्य आपको और आपके कोड को निर्भरता के प्रबंधन से मुक्त करना है। मैं आपको एक डिब कंटेनर के बिना मैन्युअल रूप से प्रभावी ढंग से करने की कल्पना नहीं कर सकता।
बोरिस यानकोव

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

4

कुछ त्वरित टिप्पणियां। मैं व्यक्तिगत रूप से शायद एक कनेक्शन स्ट्रिंग पास नहीं करूंगा। अगर कुछ भी मैं कोशिश करूं और रिपॉजिटरी के लिए इंटरफेस बनाऊं और सिर्फ इंटरफेस को पास करूं? रिपॉजिटरी को IOW इंटरफ़ेस को लागू या उजागर करना है।

इस तरह यह आपके डेटाबेस को लागू करने वाले डेटाबेस होने की आवश्यकता नहीं है। वे मेमोरी कैश, या कुछ भी हो सकते हैं। हो सकता है कि तब आप इन पर भी निर्भर करने के लिए किसी प्रकार की निर्भरता इंजेक्शन ढांचे का उपयोग कर सकें?

तो आपके कुछ सवालों के जवाब में:

  1. हां, मुझे लगता है कि यह ठीक है
  2. मैं अभी भी UI संदर्भ EF परियोजना और buisness परत संदर्भ इंटरफेस है कि EF भंडार परत लागू करता है। इस तरह से अन्य परियोजनाएं अभी भी एक ही विधानसभाओं का उपयोग कर सकती हैं, लेकिन यदि वांछित है तो उन्हें स्वैप करने की लचीलापन है?
  3. Hmmm, संभवतः एक्सेस लेयर में रिपॉजिटरी लेकिन बिजनेस लेयर में उजागर की गई इंटरफेस परिभाषा को लागू करना ??

ये केवल विचार करने के लिए कुछ विचार हैं।


बिंदु 2 के बारे में, एक लक्ष्य जो मैं बनाने की कोशिश कर रहा था वह सीधे ud परत के भीतर CRUD नहीं है। मेरा मतलब है कि मैं यह सुनिश्चित करना चाहता हूं कि केवल व्यावसायिक परत के माध्यम से ही सीआरयूडी हो सकता है, इस तरह से इसे प्रबंधित किया जाता है।
मैथ्यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.