entity framework - भंडार पैटर्न का उपयोग नहीं करते, ओआरएम का उपयोग करें(ईएफ)




entity-framework design-patterns (6)

आईएमओ दोनों Repository अमूर्तता और UnitOfWork अमूर्तता के किसी भी सार्थक विकास में एक बहुत ही मूल्यवान जगह है। लोग कार्यान्वयन के विवरण के बारे में बहस करेंगे, लेकिन जैसे ही बिल्ली को त्वचा के कई तरीके हैं, अबास्ट्रक्शन को लागू करने के कई तरीके हैं।

आपका प्रश्न विशेष रूप से उपयोग करने या उपयोग करने के लिए नहीं है और क्यों।

जैसा कि आपको कोई संदेह नहीं है कि आपके पास पहले से ही इन दोनों पैटर्नों को एंटीटी फ्रेमवर्क में बनाया गया है, DbContext और DbSet Repository । आपको आम तौर पर UnitOfWork या Repository परीक्षण करने की आवश्यकता नहीं होती है क्योंकि वे आपकी कक्षाओं और अंतर्निहित डेटा एक्सेस कार्यान्वयन के बीच आसानी से सुविधा प्रदान कर रहे हैं। जब आप अपनी सेवाओं के तर्क का परीक्षण करते हैं, तो आपको बार-बार ऐसा करने की ज़रूरत होती है, जो इन दो अबास्ट्रक्शन का मज़ाक उड़ाती है।

परीक्षण और तर्क का परीक्षण करने वाले तर्क के बीच आप नकली, नकली या जो भी बाहरी पुस्तकालयों के साथ कोड निर्भरताओं की परत जोड़ सकते हैं (जिन्हें आप नियंत्रित नहीं करते)

तो एक मामूली बात यह है कि UnitOfWork और Repository लिए अपना खुद का अमूर्त होने से आपको अपने यूनिट परीक्षणों का मज़ाक उड़ाते समय अधिकतम नियंत्रण और लचीलापन मिलता है।

सब ठीक है, लेकिन मेरे लिए, इन अवशेषों की असली शक्ति वे पहलू ओरिएंटेड प्रोग्रामिंग तकनीकों को लागू करने और सोलिड सिद्धांतों का पालन करने का एक आसान तरीका प्रदान करते हैं।

तो आपके पास अपनी IRepository :

public interface IRepository<T>
    where T : class
{
    T Add(T entity);
    void Delete(T entity);
    IQueryable<T> AsQueryable();
}

और इसके कार्यान्वयन:

public class Repository<T> : IRepository<T>
    where T : class
{
    private readonly IDbSet<T> _dbSet;
    public Repository(PPContext context) 
    {
        _dbSet = context.Set<T>();
    }

    public T Add(T entity)
    { 
        return _dbSet.Add(entity); 
    }

    public void Delete(T entity)
    {
        _dbSet.Remove(entity); 
    }

    public IQueryable<T> AsQueryable() 
    {
        return _dbSet.AsQueryable();
    }
}

अब तक साधारण से कुछ भी नहीं, लेकिन अब हम कुछ लॉगिंग जोड़ना चाहते हैं - लॉगिंग सजावट के साथ आसान।

public class RepositoryLoggerDecorator<T> : IRepository<T>
    where T : class
{
    Logger logger = LogManager.GetCurrentClassLogger();
    private readonly IRepository<T> _decorated;
    public RepositoryLoggerDecorator(IRepository<T> decorated)
    {
        _decorated = decorated;
    }

    public T Add(T entity)
    {
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString() );
        T added = _decorated.Add(entity);
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
        return added;
    }

    public void Delete(T entity)
    {
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
        _decorated.Delete(entity);
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
    }

    public IQueryable<T> AsQueryable()
    {
        return _decorated.AsQueryable();
    }
}

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

अब, मैंने कई बार इस सवाल को स्टैक ओवरफ्लो पर देखा है - "आप एक बहु किरायेदार वातावरण में एंटिटी फ्रेमवर्क कैसे काम करते हैं?"।

https://stackoverflow.com/search?q=%5Bentity-framework%5D+multi+tenant

यदि आपके पास Repository अबास्ट्रक्शन है तो जवाब है "यह एक सजावटी को जोड़ना आसान है"

public class RepositoryTennantFilterDecorator<T> : IRepository<T>
    where T : class
{
    //public for Unit Test example
    public readonly IRepository<T> _decorated;
    public RepositoryTennantFilterDecorator(IRepository<T> decorated)
    {
        _decorated = decorated;
    }

    public T Add(T entity)
    {
        return _decorated.Add(entity);
    }

    public void Delete(T entity)
    {
        _decorated.Delete(entity);
    }

    public IQueryable<T> AsQueryable()
    {
        return _decorated.AsQueryable().Where(o => true);
    }
}

आईएमओ आपको हमेशा किसी भी तीसरे पक्ष के घटक पर एक साधारण अमूर्तता रखना चाहिए जिसे कुछ हद तक स्थानों से संदर्भित किया जाएगा। इस परिप्रेक्ष्य से एक ओआरएम एक आदर्श उम्मीदवार है क्योंकि इसका हमारे कोड में संदर्भित है।

उत्तर जो आम तौर पर दिमाग में आता है जब कोई कहता है "मुझे इस पर एक अमूर्त (उदाहरण के लिए Repository ) क्यों चाहिए या वह तीसरी पार्टी लाइब्रेरी" है "आप क्यों नहीं?"

पीएस सजावटी एक आईओसी कंटेनर, जैसे SimpleInjector का उपयोग करके आवेदन करना बेहद आसान है।

[TestFixture]
public class IRepositoryTesting
{
    [Test]
    public void IRepository_ContainerRegisteredWithTwoDecorators_ReturnsDecoratedRepository()
    {
        Container container = new Container();
        container.RegisterLifetimeScope<PPContext>();
        container.RegisterOpenGeneric(
            typeof(IRepository<>), 
            typeof(Repository<>));
        container.RegisterDecorator(
            typeof(IRepository<>), 
            typeof(RepositoryLoggerDecorator<>));
        container.RegisterDecorator(
            typeof(IRepository<>), 
            typeof(RepositoryTennantFilterDecorator<>));
        container.Verify();

        using (container.BeginLifetimeScope())
        {
            var result = container.GetInstance<IRepository<Image>>();

            Assert.That(
                result, 
                Is.InstanceOf(typeof(RepositoryTennantFilterDecorator<Image>)));
            Assert.That(
                (result as RepositoryTennantFilterDecorator<Image>)._decorated,
                Is.InstanceOf(typeof(RepositoryLoggerDecorator<Image>)));
        }
    }
}

मैंने हमेशा रिपोजिटरी पैटर्न का उपयोग किया लेकिन मेरी नवीनतम परियोजना के लिए मैं देखना चाहता था कि क्या मैं इसका उपयोग कर सकता हूं और "कार्य इकाई" के कार्यान्वयन को पूरा कर सकता हूं। जितना मैंने खोदना शुरू कर दिया, मैंने खुद से सवाल पूछना शुरू किया: "क्या मुझे वाकई इसकी ज़रूरत है?"

अब यह सब स्टैक ओवरफ्लो पर दो टिप्पणियों के साथ शुरू होता है, जिसमें उनके ब्लॉग पर आयुन्द रहीन की पोस्ट के लिए एक निशान है, जिसमें 2 विशिष्ट,

यह शायद हमेशा के लिए और हमेशा के बारे में बात की जा सकती है और यह विभिन्न अनुप्रयोगों पर निर्भर करता है। मुझे क्या जानना है,

  1. क्या यह दृष्टिकोण एक इकाई फ्रेमवर्क परियोजना के लिए उपयुक्त होगा?
  2. इस दृष्टिकोण का उपयोग करना व्यापार तर्क अभी भी एक सेवा परत, या विस्तार विधियों में जा रहा है (जैसा कि नीचे बताया गया है, मुझे पता है, एक्सटेंशन विधि एनएचआईबी सत्र का उपयोग कर रही है)?

विस्तार विधियों का उपयोग करके यह आसानी से किया जाता है। स्वच्छ, सरल और पुन: प्रयोज्य।

public static IEnumerable GetAll(
    this ISession instance, Expression<Func<T, bool>> where) where T : class
{
    return instance.QueryOver().Where(where).List();
}

डीआई के रूप में इस दृष्टिकोण और Ninject का उपयोग करके, क्या मुझे Context को इंटरफ़ेस बनाने और मेरे नियंत्रकों में इंजेक्ट करने की आवश्यकता है?


इस बात पर बहुत बहस है कि कौन सी विधि सही है, इसलिए मैं इसे देखता हूं क्योंकि दोनों स्वीकार्य हैं इसलिए मैं कभी भी सबसे ज्यादा पसंद करता हूं (जो कोई भंडार नहीं है, यूओडब्ल्यू)।

ईएफ यूओडब्ल्यू में डीबीकॉन्टेक्स्ट के माध्यम से लागू किया गया है और डीबीसेट्स रिपोजिटरी हैं।

डेटा परत के साथ काम करने के तरीके के रूप में, मैं सीधे जटिल क्वेरी के लिए डीबीकॉन्टेक्स्ट ऑब्जेक्ट पर काम करता हूं, मैं क्वेरी के लिए विस्तार विधियां कर दूंगा जिसका पुन: उपयोग किया जा सकता है।

मेरा मानना ​​है कि आयुर्वे के पास कुछ पद हैं कि सीयूडी परिचालनों को कैसे खराब किया जा रहा है।

मैं हमेशा एक इंटरफ़ेस बनाता हूं और मेरा संदर्भ प्राप्त करता हूं इसलिए मैं DI के लिए एक आईओसी कंटेनर का उपयोग कर सकता हूं।


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

समस्या यह है कि कई डेवलपर्स पैटर्न उद्देश्य को समझने और रिपॉजिटरीज़ बनाने में असफल होते हैं जो कॉलर तक लगातार विशिष्ट जानकारी को रिसाव करते हैं (आमतौर पर IQueryable<T> को उजागर करके)। ऐसा करके वे सीधे OR / M का उपयोग करने पर कोई लाभ नहीं उठाते हैं।

किसी अन्य उत्तर को संबोधित करने के लिए अद्यतन करें

अपवाद के लिए कोडिंग

भंडार का उपयोग करना दृढ़ता प्रौद्योगिकी स्विच करने में सक्षम होने के बारे में नहीं है (यानी डेटाबेस बदलना या इसके बजाय एक webservice आदि का उपयोग करना)। जटिलता और युग्मन को कम करने के लिए यह व्यापार तर्क को दृढ़ता से अलग करने के बारे में है।

यूनिट परीक्षण बनाम एकीकरण परीक्षण

आप भंडार के लिए यूनिट परीक्षण नहीं लिखते हैं। अवधि।

लेकिन रिपोजिटरी (या दृढ़ता और व्यापार के बीच कोई अन्य अमूर्त परत) पेश करके आप व्यवसाय तर्क के लिए यूनिट परीक्षण लिखने में सक्षम हैं। यानी आपको गलत तरीके से कॉन्फ़िगर किए गए डेटाबेस के कारण विफल होने के बारे में चिंता करने की आवश्यकता नहीं है।

प्रश्नों के लिए के रूप में। यदि आप LINQ का उपयोग करते हैं तो आपको यह भी सुनिश्चित करना होगा कि आपके प्रश्न काम करते हैं, जैसे आपको रिपॉजिटरीज़ के साथ करना है। और यह एकीकरण परीक्षण का उपयोग कर किया जाता है।

अंतर यह है कि यदि आपने LINQ कथन के साथ अपना व्यवसाय मिश्रित नहीं किया है तो आप 100% सुनिश्चित कर सकते हैं कि यह आपका दृढ़ता कोड है जो असफल हो रहा है और कुछ और नहीं।

यदि आप अपने परीक्षणों का विश्लेषण करते हैं तो आप यह भी देखेंगे कि यदि आप मिश्रित चिंताओं (यानी LINQ + Business तर्क) नहीं हैं तो वे अधिक क्लीनर हैं

रिपोजिटरी उदाहरण

अधिकांश उदाहरण बकवास हैं। यह बिल्कुल सच है। हालांकि, अगर आप किसी भी डिजाइन पैटर्न को google करते हैं तो आपको बहुत सारे क्रैपी उदाहरण मिलेंगे। पैटर्न का उपयोग करने से बचने का कोई कारण नहीं है।

एक सही भंडार कार्यान्वयन का निर्माण बहुत आसान है। वास्तव में, आपको केवल एक नियम का पालन करना होगा:

रिपोजिटरी क्लास में कुछ भी उस समय तक न जोड़ें जब तक आपको इसकी आवश्यकता न हो

बहुत सारे कोडर आलसी हैं और एक सामान्य भंडार बनाने की कोशिश करते हैं और बेस क्लास का उपयोग कई तरीकों से करते हैं जिनकी उन्हें आवश्यकता हो सकती है। YAGNI। आप एक बार भंडार वर्ग लिखते हैं और जब तक एप्लिकेशन रहता है तब तक इसे बनाए रखें (वर्षों हो सकते हैं)। आलसी होने के कारण इसे बकवास क्यों करें। किसी भी बेस क्लास विरासत के बिना इसे साफ रखें। यह पढ़ने और बनाए रखने के लिए इसे और अधिक आसान बना देगा।

(उपर्युक्त कथन एक दिशानिर्देश है, न कि कानून। आधार वर्ग बहुत अच्छी तरह से प्रेरित हो सकता है। इसे जोड़ने से पहले सोचें, ताकि आप इसे सही कारणों से जोड़ सकें)

पुरानी सामग्री

निष्कर्ष:

यदि आपको अपने व्यापार कोड में LINQ कथन नहीं है और न ही यूनिट परीक्षणों की परवाह नहीं है, तो मुझे सीधे इकाई फ्रेमवर्क का उपयोग करने का कोई कारण नहीं दिखता है।

अद्यतन करें

मैंने दोनों को भंडार पैटर्न के बारे में ब्लॉग किया है और वास्तव में क्या "अमूर्तता" का अर्थ है: http://blog.gauffin.org/2013/01/repository-pattern-done-right/

अद्यतन 2

20+ फ़ील्ड वाले एकल इकाई प्रकार के लिए, आप किसी भी क्रमपरिवर्तन संयोजन का समर्थन करने के लिए क्वेरी विधि कैसे डिज़ाइन करेंगे? आप केवल नाम से खोज सीमित नहीं करना चाहते हैं, नेविगेशन गुणों के साथ खोज के बारे में क्या, विशिष्ट मूल्य कोड वाले आइटम के साथ सभी ऑर्डर सूचीबद्ध करें, नेविगेशन प्रॉपर्टी सर्च के 3 स्तर। IQueryable का पूरा कारण आविष्कार किया गया था डेटाबेस के खिलाफ खोज के किसी भी संयोजन को लिखने में सक्षम होना था। सब कुछ सिद्धांत में महान दिखता है, लेकिन उपयोगकर्ता की आवश्यकता सिद्धांत से ऊपर जीत जाती है।

दोबारा: 20+ फ़ील्ड वाले एक इकाई को गलत तरीके से मॉडलिंग किया गया है। यह एक ईश्वरीय इकाई है। तोड़ दो।

मैं बहस नहीं कर रहा हूं कि IQueryable quering के लिए नहीं बनाया गया था। मैं कह रहा हूं कि यह एक अवशोषण परत के लिए सही नहीं है जैसे रिपोजिटरी पैटर्न यह रिसाव है। एसक्यूएल प्रदाता (जैसे ईएफ) के लिए कोई 100% पूर्ण LINQ नहीं है।

उन सभी में कार्यान्वित विशिष्ट चीजें हैं जैसे कि उत्सुक / आलसी लोडिंग या SQL "IN" कथन कैसे करें। भंडार में IQueryable का IQueryable करने वाले उपयोगकर्ता को उन सभी चीजों को जानने के लिए मजबूर करता है। इस प्रकार डेटा स्रोत को दूर करने का पूरा प्रयास एक पूर्ण विफलता है। आप सीधे OR / M का उपयोग करने पर कोई लाभ प्राप्त किए बिना जटिलता जोड़ते हैं।

या तो रिपोजिटरी पैटर्न को सही ढंग से कार्यान्वित करें या बस इसका उपयोग न करें।

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


मैंने कई मार्गों को छोड़ दिया है और विभिन्न परियोजनाओं पर भंडारों के कई कार्यान्वयन बनाए हैं और ... मैंने तौलिया फेंक दिया है और इसे छोड़ दिया है, यही कारण है कि।

अपवाद के लिए कोडिंग

क्या आप 1% मौके के लिए कोड करते हैं कि आपका डेटाबेस एक तकनीक से दूसरे तकनीक में बदल जाएगा? यदि आप अपने व्यापार के भविष्य के बारे में सोच रहे हैं और हाँ कहें तो यह संभावना है कि ए) उनके पास एक और डीबी प्रौद्योगिकी के लिए माइग्रेशन करने के लिए बहुत पैसा होना चाहिए या बी) आप मजेदार या सी के लिए डीबी तकनीक चुन रहे हैं ) आपके द्वारा उपयोग किए जाने वाले पहले तकनीक के साथ कुछ गड़बड़ हो गई है।

समृद्ध LINQ वाक्यविन्यास क्यों फेंक दें?

LINQ और EF विकसित किए गए थे ताकि ऑब्जेक्ट ग्राफ़ को पढ़ने और ट्रैवर्स करने के लिए आप इसके साथ साफ-सुथरा सामान कर सकें। एक भंडार बनाना और बनाए रखना जो आपको ऐसा करने के लिए समान लचीलापन दे सकता है वह एक राक्षसी कार्य है। मेरे अनुभव में जब भी मैंने एक रिपोजिटरी बनाई है, तो मेरे पास हमेशा रिपोजिटरी परत में व्यापार तर्क रिसाव होता है या तो क्वेरी को अधिक निष्पादित करता है और / या डेटाबेस में हिट की संख्या को कम करता है।

मैं एक प्रश्न के प्रत्येक क्रमपरिवर्तन के लिए एक विधि नहीं बनाना चाहता हूं जिसे मुझे लिखना है। मैं संग्रहित प्रक्रियाओं को भी लिख सकता हूं। मैं GetOrder नहीं चाहता, GetOrderWithOrderItem, GetOrderWithOrderItemWithOrderActivity, GetOrderByUserId, और इसी तरह ... मैं बस मुख्य इकाई प्राप्त करना चाहता हूं और ट्रैवर्स और ऑब्जेक्ट ग्राफ़ को शामिल करना चाहता हूं।

भंडार के अधिकांश उदाहरण बकवास हैं

जब तक कि आप कुछ ऐसी चीजें विकसित नहीं कर रहे हैं जो वास्तव में एक ब्लॉग की तरह नंगे हड्डियों या कुछ प्रश्न हैं जो आपके प्रश्नों को रिपोजिटरी पैटर्न के आस-पास के इंटरनेट पर मिलने वाले उदाहरणों में से 9 0% जितना आसान नहीं होगा। मैं इस पर अधिक जोर नहीं दे सकता हूं! यह ऐसा कुछ है जिसे किसी को मिट्टी के माध्यम से समझने के लिए क्रॉल करना पड़ता है। हमेशा एक ऐसी क्वेरी होगी जो आपके द्वारा बनाई गई पूरी तरह से सोचा गया भंडार / समाधान तोड़ती है, और यह उस बिंदु तक नहीं है जहां आप अपना दूसरा अनुमान लगाते हैं और तकनीकी ऋण / क्षरण शुरू होता है।

यूनिट परीक्षण मुझे ब्रो

लेकिन अगर मेरे पास भंडार नहीं है तो यूनिट परीक्षण के बारे में क्या? मैं कैसे नकल करूंगा? सरल आप नहीं करते हैं। आइए इसे दोनों कोणों से देखें:

कोई भंडार नहीं - आप आईडीबीकॉन्टेक्स्ट या किसी अन्य चाल का उपयोग करके डीबीकॉन्टेक्स्ट का नकल कर सकते हैं लेकिन फिर आप वाकई यूनिट परीक्षण LINQ ऑब्जेक्ट्स और LINQ से इकाइयों तक नहीं हैं क्योंकि क्वेरी रनटाइम पर निर्धारित होती है ... ठीक है तो यह अच्छा नहीं है! तो अब इसे कवर करने के लिए एकीकरण परीक्षण तक।

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

2 सेंट

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

मुझे उम्मीद है कि यह किसी को इंटर्ननेट पर कहीं मदद करता है ...


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

यूनिट टेस्ट के लिए नकली रिपोजिटरी, क्या हमें वास्तव में इसकी आवश्यकता है?

हम ईएफएफ को एसक्यूएल टेस्ट डीबी के खिलाफ सीधे अपने व्यापार तर्क का परीक्षण करने के लिए यूनिट परीक्षणों में डीबी का परीक्षण करने के लिए संवाद करने देते हैं। मुझे किसी भी भंडार पैटर्न के नकली होने का कोई लाभ नहीं दिखता है। परीक्षण डेटाबेस के खिलाफ यूनिट परीक्षण वास्तव में गलत क्या है? चूंकि यह थोक संचालन संभव नहीं है और हम कच्चे एसक्यूएल लिखते हैं। स्मृति में SQLite असली डेटाबेस के खिलाफ यूनिट परीक्षण करने के लिए एकदम सही उम्मीदवार है।

अनावश्यक अमूर्तता

क्या आप सिर्फ भंडार बनाना चाहते हैं ताकि भविष्य में आप एनएफबीबेरनेट आदि के साथ ईएफ को आसानी से बदल सकें या कुछ और? महान योजना लगता है, लेकिन क्या यह वास्तव में लागत प्रभावी है?

लिंक यूनिट परीक्षण मारता है?

मैं किसी भी उदाहरण को देखना चाहूंगा कि यह कैसे मार सकता है।

निर्भरता इंजेक्शन, आईओसी

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

जब तक आप विजुअल स्टूडियो नहीं बना रहे हों

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

रिपोजिटरी फ़िल्टर फ़िल्टर के रूप में - ISecureRepository

दूसरी ओर, भंडार ईएफ का फ़िल्टर किया गया दृश्य होना चाहिए जो वर्तमान उपयोगकर्ता / भूमिका के आधार पर आवश्यक filler लागू करके डेटा तक पहुंच प्रदान करता है।

लेकिन ऐसा करने के लिए भारी कोड बेस में समाप्त होने के साथ-साथ भंडार को और भी जटिल बनाते हैं। लोग विभिन्न उपयोगकर्ता प्रकारों या इकाई प्रकारों के संयोजन के लिए अलग-अलग भंडार तैयार करते हैं। इतना ही नहीं, हम भी कई डीटीओ के साथ खत्म हो जाते हैं।

निम्नलिखित उत्तर कक्षाओं और विधियों के पूरे सेट के बिना फ़िल्टर किए गए रिपोजिटरी का एक उदाहरण कार्यान्वयन है। यह सीधे सवाल का जवाब नहीं दे सकता है लेकिन यह एक प्राप्त करने में उपयोगी हो सकता है।

अस्वीकरण: मैं एंटिटी रीस्ट एसडीके के लेखक हूं।

http://entityrestsdk.codeplex.com

ध्यान में रखते हुए, हमने एक एसडीके विकसित किया जो सुरक्षा कॉन्टेक्स्ट के आधार पर फ़िल्टर किए गए दृश्य की भंडार बनाता है जिसमें सीआरयूडी संचालन के लिए फ़िल्टर हैं। और केवल दो प्रकार के नियम किसी जटिल परिचालन को सरल बनाते हैं। सबसे पहले इकाई तक पहुंच है, और अन्य संपत्ति के लिए नियम पढ़ें / लिखें।

लाभ यह है कि आप विभिन्न उपयोगकर्ता प्रकारों के लिए व्यावसायिक तर्क या भंडार को फिर से लिखना नहीं चाहते हैं, आप बस उन्हें अवरुद्ध या पहुंच प्रदान करते हैं।

public class DefaultSecurityContext : BaseSecurityContext {

  public static DefaultSecurityContext Instance = new DefaultSecurityContext();

  // UserID for currently logged in User
  public static long UserID{
       get{
             return long.Parse( HttpContext.Current.User.Identity.Name );
       }
  }

  public DefaultSecurityContext(){
  }

  protected override void OnCreate(){

        // User can access his own Account only
        var acc = CreateRules<Account>();

        acc.SetRead( y => x=> x.AccountID == UserID ) ;
        acc.SetWrite( y => x=> x.AccountID == UserID );

        // User can only modify AccountName and EmailAddress fields
        acc.SetProperties( SecurityRules.ReadWrite, 
              x => x.AccountName,
              x => x.EmailAddress);

        // User can read AccountType field
        acc.SetProperties<Account>( SecurityRules.Read, 
              x => x.AccountType);

        // User can access his own Orders only
        var order = CreateRules<Order>();
        order.SetRead( y => x => x.CustomerID == UserID );

        // User can modify Order only if OrderStatus is not complete
        order.SetWrite( y => x => x.CustomerID == UserID 
            && x.OrderStatus != "Complete" );

        // User can only modify OrderNotes and OrderStatus
        order.SetProperties( SecurityRules.ReadWrite, 
              x => x.OrderNotes,
              x => x.OrderStatus );

        // User can not delete orders
        order.SetDelete(order.NotSupportedRule);
  }
}

इन LINQ नियमों का मूल्यांकन प्रत्येक ऑपरेशन के लिए SaveChanges विधि में डेटाबेस के विरुद्ध किया जाता है, और ये नियम डेटाबेस के सामने फ़ायरवॉल के रूप में कार्य करते हैं।


For me, it's a simple decision, with relatively few factors. The factors are:

  1. Repositories are for domain classes.
  2. मेरे कुछ ऐप्स में, डोमेन क्लासेस मेरे दृढ़ता (डीएएल) कक्षाओं के समान हैं, अन्य में वे नहीं हैं।
  3. जब वे वही होते हैं, तो ईएफ मुझे पहले से ही रेपॉजिटरीज़ प्रदान कर रहा है।
  4. ईएफ आलसी लोडिंग और IQueryable प्रदान करता है। मैं इन्हे पसन्द करता हूँ।
  5. ईएफ पर सारणी / 'मुखौटा' / पुन: कार्यान्वयन भंडार आमतौर पर आलसी और IQueryable का नुकसान

इसलिए, यदि मेरा ऐप # 2, अलग डोमेन और डेटा मॉडल को उचित नहीं ठहरा सकता है, तो मैं आमतौर पर # 5 से परेशान नहीं होगा।





repository-pattern