DDD

2013-06-08 3 views
5

में AggregateRoots में डोमेन सेवा इंजेक्शन DDD में सामान्यतः ज्ञात सलाह है कि एक सकल जड़ें उपयोगकर्ता नहीं एक डोमेन सेवा करते हैं। डोमेन सेवा एक व्यवहार प्राप्त करने के लिए दो समग्र रूट समन्वयित करना है।DDD

जब मैं इस ब्लॉग शीर्षक Building Blocks Of CQRS साथ Rinat Abdullin द्वारा लिखित देखा यह वास्तव में मुझे हैरान कर दिया। डोमेन सेवा अनुभाग के तहत, आप पढ़ लेंगे कि एक डोमेन सेवा को कुल रूट में इंजेक्शन दिया जाता है।

एक सकल रूट एक डोमेन सेवा स्वीकार कर सकते हैं?

उत्तर

4

कृपया, उपेक्षा है कि लेख। यह बहुत समय पहले लिखा गया था और सादा गलत है।

  1. की मदद से कुल
  2. प्रदर्शन गणना लोड हो रहा है: अगर AggregateRoot और DomainService पैटर्न के साथ एक मॉड्यूल को लागू करने, मैं एक उच्च तर्क (जैसे अनुरोध हैंडलर) जो के लिए जिम्मेदार है के लिए सिफारिश करेंगे डोमेन सेवाएं
  3. तदनुसार कुल राज्य को म्यूट करना।
+1

रीनाट है, क्या आप अपने पुराने लेखों पर बैनर नहीं रखना चाहते हैं, जो उत्तर में आपने जो लिखा है उसे दोहराएगा? लोग अक्सर आपके ब्लॉग को विचारों और सर्वोत्तम प्रथाओं के लिए संदर्भित करते हैं लेकिन आप निश्चित रूप से जानते हैं कि कुछ वर्णित अभ्यास वास्तव में सर्वश्रेष्ठ नहीं हैं ... कोई अपराध नहीं, केवल एक सुझाव है। –

3

डोमेन ऑब्जेक्ट्स में कुछ भी इंजेक्ट करना बहुत कठिन है, और ऐसा करना काफी तकनीकी विशिष्ट है। जावा में इसे आपके डोमेन वर्गों में पहलुओं के बुनाई के समय को संकलित करने की आवश्यकता होती है। और यद्यपि मैं इस पर गलत हो सकता था, मुझे लगता है कि ज्यादातर डीडीडी नेता सोचते हैं कि यह आम तौर पर एक बुरा विचार है। Evans और Vernon दोनों सक्रिय रूप से इसे हतोत्साहित करते हैं, और मैं उन्हें सुनना पसंद करता हूं। पूर्ण स्पष्टीकरण के लिए, वर्नन पढ़ें।

+0

मैं मानता हूँ कि इवांस और वेर्नोन Rinat का विचार करने के लिए सहमत नहीं हैं। उदाहरण में, वह LockCustomerForAccountOverdraft विधि में थ्रेसहोल्ड खोजने के लिए मूल्य निर्धारण सेवा का उपयोग करता है। यह एक व्यापार नियम मूल्यांकन है जिसे कमांड भेजकर किया जा सकता है। इवान और वर्सन के दृष्टिकोण के साथ, लॉक कस्टमर नामक एक उच्च स्तरीय डोमेन सेवा होनी चाहिए जहां मूल्य निर्धारण सेवा और ग्राहक एग्रीगेट का समन्वय किया जा सकता है। मुझे लगता है कि इवांस और वेरनॉन एसआरपी लागू करते हैं इसलिए अधिक घटक हैं। रिनाट एक साधारण दृष्टिकोण लेता है, इसलिए वह ग्राहक के लिए इस मामले में खुले/बंद सिद्धांत को तोड़ने के साथ ठीक हो सकता है। –

7

एक तरह से हाँ। यदि एआर को वास्तव में कुछ नौकरी के करने की सेवा की आवश्यकता है, तो आप इसे विधि तर्क के रूप में इंजेक्ट कर सकते हैं। यदि एआर को के लिए के व्यवहार की आवश्यकता है तो शायद इसे गलत तरीके से मॉडलिंग किया गया है।

+0

यदि दोनों सेवाएं एक ही बाध्य संदर्भ में रहते हैं, तो कुल जड़ें संदेशों के माध्यम से एक-दूसरे से बात कर सकती हैं, तो सेवा को इंजेक्शन क्यों जरूरी है? –

+1

यह केवल तभी जरूरी है जब एआर को कुछ व्यवहार करने की आवश्यकता हो। मैं नहीं देखता कि मैसेजिंग कैसे मदद करेगी। – MikeSW

+0

मैंने यहां गलत शब्द का उपयोग किया होगा। मेरा मतलब डोमेन कार्यक्रम था। –

2

मैं following explanation काफी अच्छा लगता है। यह वॉन वर्नॉन द्वारा पुस्तक पर आधारित है और विधि कॉल के माध्यम से डोमेन मॉडल में डोमेन सेवा को इंजेक्ट करता है जिसे वास्तव में इस सेवा की आवश्यकता होती है।

public class PurchaseOrder 
{ 
    public string Id { get; private set; } 
    public string VendorId { get; private set; } 
    public string PONumber { get; private set; } 
    public string Description { get; private set; } 
    public decimal Total { get; private set; } 
    public DateTime SubmissionDate { get; private set; } 
    public ICollection<Invoice> Invoices { get; private set; } 

    public decimal InvoiceTotal 
    { 
     get { return this.Invoices.Select(x => x.Amount).Sum(); } 
    } 

    public bool IsFullyInvoiced 
    { 
     get { return this.Total <= this.InvoiceTotal; } 
    } 

    bool ContainsInvoice(string vendorInvoiceNumber) 
    { 
     return this.Invoices.Any(x => x.VendorInvoiceNumber.Equals(
      vendorInvoiceNumber, StringComparison.OrdinalIgnoreCase)); 
    } 

    public Invoice Invoice(IInvoiceNumberGenerator generator, 
     string vendorInvoiceNumber, DateTime date, decimal amount) 
    { 
     // These guards maintain business integrity of the PO. 
     if (this.IsFullyInvoiced) 
      throw new Exception("The PO is fully invoiced."); 
     if (ContainsInvoice(vendorInvoiceNumber)) 
      throw new Exception("Duplicate invoice!"); 

     var invoiceNumber = generator.GenerateInvoiceNumber(
      this.VendorId, vendorInvoiceNumber, date); 

     var invoice = new Invoice(invoiceNumber, vendorInvoiceNumber, date, amount); 
     this.Invoices.Add(invoice); 
     DomainEvents.Raise(new PurchaseOrderInvoicedEvent(this.Id, invoice.InvoiceNumber)); 
     return invoice; 
    } 
} 

public class PurchaseOrderService 
{ 
    public PurchaseOrderService(IPurchaseOrderRepository repository, 
     IInvoiceNumberGenerator invoiceNumberGenerator) 
    { 
     this.repository = repository; 
     this.invoiceNumberGenerator = invoiceNumberGenerator; 
    } 

    readonly IPurchaseOrderRepository repository; 
    readonly IInvoiceNumberGenerator invoiceNumberGenerator; 

    public void Invoice(string purchaseOrderId, 
     string vendorInvoiceNumber, DateTime date, decimal amount) 
    { 
     // Transaction management, along with committing the unit of work 
     // can be moved to ambient infrastructure. 
     using (var ts = new TransactionScope()) 
     { 
      var purchaseOrder = this.repository.Get(purchaseOrderId); 
      if (purchaseOrder == null) 
       throw new Exception("PO not found!"); 
      purchaseOrder.Invoice(this.invoiceNumberGenerator, 
       vendorInvoiceNumber, date, amount); 
      this.repository.Commit(); 
      ts.Complete(); 
     } 
    } 
} 
+0

खरीदऑर्डर सेवा एक सेवा सेवा है जो डोमेन सेवा नहीं है, जैसा कि मैं इसे समझता हूं। –

+2

@ वंडरफुलवर्ल्ड: IInvoiceNumberGenerator डोमेन सेवा – mynkow

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