2009-03-16 12 views
7

मुझे लगता है कि मुझे इस पूरे डीडीडी \ LinqToSql व्यवसाय के भ्रम में थोड़ा सा मिल गया है। मैं एसओसीएल के लिए पीओसीओएस और लिनक का उपयोग कर एक सिस्टम बना रहा हूं और मेरे पास कुल जड़ों के लिए भंडार हैं। तो, उदाहरण के लिए यदि आपके पास कक्षाएं ऑर्डर-> ऑर्डरलाइन है तो आपके पास ऑर्डर के लिए एक रिपोजिटरी है लेकिन आदेश के रूप में ऑर्डरलाइन नहीं है, कुल की जड़ है। ऑर्डर हटाने के लिए रिपॉजिटरी में डिलीट विधि है, लेकिन आप ऑर्डरलाइन को कैसे हटाते हैं? आपने सोचा होगा कि आपके पास RemoveOrderLine नामक ऑर्डर पर एक विधि है जिसने ऑर्डरलाइन संग्रह से लाइन को हटा दिया है, लेकिन इसे अंतर्निहित एल 2 एस तालिका से ऑर्डरलाइन को भी हटाने की आवश्यकता है। चूंकि ऑर्डरलाइन के लिए कोई भंडार नहीं है, आपको इसे कैसे करना है?डोमेन संचालित डिजाइन (एसक्यूएल से लिंक) - आप कुल के हिस्सों को कैसे हटाते हैं?

शायद जड़ों और आंतरिक जेनेरिक भंडारों की पूछताछ के लिए विशेष सार्वजनिक रिपोस्टरीज हैं जो डोमेन ऑब्जेक्ट्स वास्तव में योगों के भीतर सामान को हटाने के लिए उपयोग करते हैं?

public class OrderRepository : Repository<Order> { 
    public Order GetOrderByWhatever(); 
} 

public class Order { 
    public List<OrderLines> Lines {get; set;} //Will return a readonly list 
    public RemoveLine(OrderLine line) { 
     Lines.Remove(line); 
     //************* NOW WHAT? *************// 
     //(new Repository<OrderLine>(uow)).Delete(line) Perhaps?? 
     // But now we have to pass in the UOW and object is not persistent ignorant. AAGH! 
    } 
} 

मुझे पता है कि अन्य लोगों को नहीं कर सकते के रूप में मैं केवल एक इस के साथ संघर्ष कर .... मुझे आशा है कि हो सकता है क्या किया है प्यार होता है .... धन्यवाद

उत्तर

2

आप आदेश पर RemoveOrderLine फोन जो संबंधित तर्क को बुलाओ। इसमें इसके निरंतर संस्करण पर परिवर्तन करने शामिल नहीं हैं।

बाद में आप भंडार पर एक सहेजें/अद्यतन विधि को कॉल करते हैं, जो संशोधित आदेश प्राप्त करता है। विशिष्ट चुनौती डोमेन ऑब्जेक्ट में क्या बदल गई है, यह जानने में बन जाती है, जिसमें कई विकल्प हैं (मुझे यकीन है कि मेरी सूची में से अधिक हैं):

  • डोमेन ऑब्जेक्ट में परिवर्तनों का ट्रैक रखना है, जो ट्रैक रखने में शामिल होगा कि एक्स को ऑर्डर लाइनों से हटा दिया जाना चाहिए। इकाई ट्रैकिंग के समान कुछ भी हो सकता है।
  • निरंतर संस्करण लोड करें। भंडार में कोड है जो लगातार संस्करण और इन-मेमोरी संस्करण के बीच अंतर को पहचानता है, और परिवर्तन चलाता है।
  • निरंतर संस्करण लोड करें। जड़ कुल में कोड है, जो आपको मूल रूट कुल मिलाकर अंतर देता है।
+0

मुझे लगता है कि इस विस्तार का अर्थ है कि आप सीधे अपने डोमेन इकाइयों पर ओआरएम का उपयोग नहीं कर रहे हैं। मैं ऊपर वर्णित अतिरिक्त कार्य से बचने में सक्षम होने की उम्मीद कर रहा था, एसक्यूएल को एसक्यूएल स्वचालित रूप से डोमेन ऑब्जेक्ट में किए गए परिवर्तनों को जारी रखकर ... –

+0

y, यह वास्तविक समस्या है। मैं उपरोक्त कर रहा हूं। मैं निबर्ननेट पर अधिक उन्नत परिदृश्यों का समर्थन करने पर हर समय टिप्पणियां देखता हूं, लेकिन मैंने इस प्रकार के परिदृश्य (जो सिर्फ पीओसीओ का उपयोग नहीं कर रहा है) के साथ यह कैसे देखा है, – eglasius

+0

धन्यवाद; यद्यपि बहुत आदर्श नहीं है (एलटीएस की गलती, आपका जवाब नहीं) ऐसा लगता है कि मुझे यह कैसे करना होगा ... – Funka

1

सबसे पहले, आपको अपने कुल रूट (यानी ऑर्डर()) के संदर्भ प्राप्त करने के लिए इंटरफेस का खुलासा करना चाहिए। समग्र रूट (यानी ऑर्डर()) के नए उदाहरण को नए अप करने के लिए फैक्टरी पैटर्न का उपयोग करें।

इसके साथ ही, आपके कुल रूट contros के तरीकों से संबंधित वस्तुओं तक पहुंच - स्वयं नहीं। साथ ही, समग्र जड़ों पर सार्वजनिक रूप से जटिल प्रकारों का खुलासा न करें (यानी लाइन्स() उदाहरण सूची में आपने कहा था। यह कमीशन (एसपी सीके) के कानून का उल्लंघन करता है, जो कहता है कि आप आदेशों के लिए अपना रास्ता "डॉट वाक" नहीं कर सकते हैं, जैसे ऑर्डर। लाइन्स। जोड़ें()।

और साथ ही, आप उस नियम का उल्लंघन करते हैं जो क्लाइंट को समग्र रूट पर किसी आंतरिक ऑब्जेक्ट के संदर्भ तक पहुंचने की अनुमति देता है। कुल जड़ें एक आंतरिक वस्तु का संदर्भ वापस कर सकते हैं। जब तक, बाहरी क्लाइंट को उस ऑब्जेक्ट का संदर्भ रखने की अनुमति नहीं है। यानी, आपका "ऑर्डरलाइन" आप RemoveLine() में जाते हैं। आप बाहरी क्लाइंट को अपने मॉडल की आंतरिक स्थिति (यानी ऑर्डर() और इसकी ऑर्डरलाइन()) को नियंत्रित करने की अनुमति नहीं दे सकते। इसलिए, आपको ऑर्डरलाइन को तदनुसार कार्य करने के लिए एक नया उदाहरण होने की उम्मीद करनी चाहिए।

public interface IOrderRepository 
{ 
    Order GetOrderByWhatever(); 
} 

internal interface IOrderLineRepository 
{ 
    OrderLines GetOrderLines(); 
    void RemoveOrderLine(OrderLine line); 
} 

public class Order 
{ 
    private IOrderRepository orderRepository; 
    private IOrderLineRepository orderLineRepository; 
    internal Order() 
    { 
    // constructors should be not be exposed in your model. 
    // Use the Factory method to construct your complex Aggregate 
    // Roots. And/or use a container factory, like Castle Windsor 
    orderRepository = 
      ComponentFactory.GetInstanceOf<IOrderRepository>(); 
    orderLineRepository = 
      ComponentFactory.GetInstanceOf<IOrderLineRepository>(); 
    } 
    // you are allowed to expose this Lines property within your domain. 
    internal IList<OrderLines> Lines { get; set; } 
    public RemoveOrderLine(OrderLine line) 
    { 
    if (this.Lines.Exists(line)) 
    { 
     orderLineRepository.RemoveOrderLine(line); 
    } 
    } 
} 

आदेश() के नए उदाहरणों बनाने के लिए अपने कारखाने को न भूलें:

public class OrderFactory 
{ 
    public Order CreateComponent(Type type) 
    { 
    // Create your new Order.Lines() here, if need be. 
    // Then, create an instance of your Order() type. 
    } 
} 

आपका बाहरी ग्राहक को सीधे IOrderLinesRepository का उपयोग करने का अधिकार है, इंटरफ़ेस एक संदर्भ के माध्यम से प्राप्त करने के लिए आपके कुल रूट के भीतर एक मूल्य वस्तु का। लेकिन, मैं अपने रूट को कुल रूट के तरीकों से दूर करने के लिए इसे अवरुद्ध करने का प्रयास करता हूं। तो, आप IOrderLineRepository को आंतरिक के रूप में ऊपर चिह्नित कर सकते हैं ताकि यह खुलासा न हो।

मैं वास्तव में कई सारे कारखानों में अपनी कुल रूट रचनाओं को समूहित करता हूं। मुझे इस दृष्टिकोण को पसंद नहीं आया, "कुछ कुल जड़ें जटिल प्रकारों के लिए कारखानों में होंगी, अन्य नहीं होंगे"। पूरे डोमेन मॉडलिंग के दौरान एक ही तर्क का पालन करना बहुत आसान है। "ओह, तो बिक्री() ऑर्डर() जैसी कुल जड़ है। इसके लिए एक कारखाना भी होना चाहिए।"

एक अंतिम नोट यह है कि यदि संयोजन है, यानी SalesOrder(), जो बिक्री() और ऑर्डर() के दो मॉडल का उपयोग करता है, तो आप SalesOrder() के उस उदाहरण पर बनाने और कार्य करने के लिए एक सेवा का उपयोग करेंगे क्योंकि न तो बिक्री() या आदेश() कुल रूट, न ही उनके भंडार या कारखानों, SalesOrder() इकाई पर अपना नियंत्रण।

मैं अत्यधिक, this free book को डोमेन ड्राइव डिज़ाइन (डीडीडी) पर हाबिल एवरम और फ़्लॉइड मरिनेस्कू द्वारा अत्यधिक अनुशंसा करता हूं क्योंकि यह सीधे आपके प्रश्नों का उत्तर देता है, एक पृष्ठ 100 बड़े प्रिंट में। मॉड्यूल और ऐसे में अपनी डोमेन इकाइयों को और अधिक कम करने के तरीके के साथ-साथ।

संपादित करें: जोड़ा अधिक कोड

+0

प्रतिक्रिया के लिए धन्यवाद।मुझे यकीन नहीं है कि ऑर्डर पर विधियों के माध्यम से उजागर ऑर्डर लाइन का व्यवहार करने के बारे में। ऐसा लगता है कि GetOrderLineVatAmount लाइन पर होना चाहिए अन्यथा आपको क्रम में फ़ंक्शन में लाइन को पास करना होगा। इसके अलावा, ऑर्डर रेपोस के लिए ऑर्डर क्यों होगा? –

+0

यह सब इस बात पर निर्भर करता है कि आप "ऑर्डरलाइन" कैसे देखते हैं। उपरोक्त कोड "मूल्य वस्तु" दृष्टिकोण को दर्शाता है। एक वैल्यू ऑब्जेक्ट एक इकाई से अलग है जिस तरह से इसकी पहचान नहीं होती है। क्या प्रत्येक ऑर्डरलाइन की पहचान होती है? यदि हां, तो क्या आप वास्तव में ऐसा सोचते हैं? – eduncan911

+0

OrderLine.LineNumber OrderLine.Description OrderLine.Cost OrderLine.PartNumber एक मूल्य वस्तु यहां की परिभाषा एक पहचान में नहीं है, लेकिन, इसके मूल्यों का सारांश। लेकिन जैसा कि मैंने उत्तर में ऊपर बताया है, आप IOrderLineRepository() का खुलासा कर सकते हैं और आपके रिमोट क्लाइंट के पास पहुंचने का अधिकार है। – eduncan911

0

के रूप में एक मैं nhibernate का उपयोग कर (बल्कि एसक्यूएल के लिए लिंक की तुलना में), लेकिन प्रभाव में आप ऑर्डर लाइन के लिए रेपोस की आवश्यकता नहीं है में बदला गया है अनुवर्ती ....। यदि आप आदेश में संग्रह से ऑर्डरलाइन को हटाते हैं तो यह डेटाबेस से ऑर्डरलाइन को हटा देगा (मान लीजिए कि आपने अपना मैपिंग सही तरीके से किया है)। जैसा कि मैं इन-मेमोरी रिपॉजिटरीज़ के साथ स्वैपिंग कर रहा हूं, यदि आप किसी विशेष ऑर्डर लाइन (ऑर्डर पेरेंट को जानने के बिना) खोजना चाहते हैं तो आप ऑर्डरलाइन के लिए ऑर्डरलाइन ऑर्डर करने के लिए ऑर्डर लिंक करने के लिए लिंक्स लिख सकते हैं। इस तरह यह डीबी से और स्मृति में पूछताछ करते समय काम करता है। वैसे आप वहाँ जाते हैं ...

+0

बमर, मैं वास्तव में उम्मीद कर रहा था कि किसी को आपके (बहुत उत्कृष्ट, और बहुत प्रासंगिक!) प्रश्न का बेहतर उत्तर मिलेगा, इसे करने के लिए लिंक से एसक्यूएल को त्यागने के बिना! – Funka

1

इस सटीक मुद्दे के साथ संघर्ष करने के बाद, मुझे समाधान मिला है। एल 2 एसएल के साथ डिजाइनर क्या उत्पन्न करता है, यह देखने के बाद, मुझे एहसास हुआ कि समाधान ऑर्डर और ऑर्डरलाइन के बीच दो-तरफा संगठनों में है। एक आदेश में कई ऑर्डरलाइन हैं और ऑर्डरलाइन में एक ही ऑर्डर है। समाधान दो तरह के संगठनों और एक मैपिंग विशेषता का उपयोग करना है जिसे DeleteOnNull (जिसे आप पूरी जानकारी के लिए Google कर सकते हैं) कहा जाता है। आखिरी चीज जो मुझे याद आ रही थी वह यह था कि आपकी इकाई वर्ग को l2s entityset से ईवेंट जोड़ने और निकालने के लिए पंजीकरण करने की आवश्यकता है। इन हैंडलरों में, आपको ऑर्डर एसोसिएशन को ऑर्डर लाइन पर शून्य होना होगा। यदि आप कुछ कोड देखते हैं जो l2s डिज़ाइनर उत्पन्न करता है तो आप इसका एक उदाहरण देख सकते हैं।

मुझे पता है कि यह एक निराशाजनक है, लेकिन इसके साथ संघर्ष करने के दिनों के बाद, मुझे यह काम मिल गया है।

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