11

में नई इकाई आईडी मैं सीक्यूआरएस और डोमेन इवेंट अवधारणाओं का उपयोग कर एक डोमेन मॉडल के साथ एक एप्लिकेशन बना रहा हूं (लेकिन कोई ईवेंट सोर्सिंग नहीं, केवल सादा पुराना एसक्यूएल)। SomethingChanged तरह की घटनाओं के साथ कोई समस्या नहीं थी। तब मैं SomethingCreated घटनाओं को लागू करने में फंस गया।डोमेन इवेंट

जब मैं कुछ इकाई जो पहचान प्राथमिक कुंजी के साथ एक मेज के लिए मैप किया गया है तो मैं ईद पता नहीं है जब तक इकाई एक समान होती है पैदा करते हैं। इकाई दृढ़ता से अज्ञान है इसलिए जब इकाई के अंदर से एक ईवेंट प्रकाशित करते हैं, तो आईडी को अभी ज्ञात नहीं है - यह जादुई रूप से संदर्भ को कॉल करने के बाद सेट किया गया है। केवल चावे चेंज()। तो मैं इवेंट डेटा में आईडी/कब/कब रख सकता हूं? घटना में इकाई के संदर्भ में भी शामिल है

  • :

    मैं के बारे में सोच रहा था। यह डोमेन के अंदर काम करेगा लेकिन घटनाओं/संदेशों द्वारा संचारित कई स्वायत्त प्रणाली के साथ एक वितरित वातावरण में नहीं।

  • SaveChanges() को ओवरराइड करने के लिए किसी भी तरह से प्रकाशन के लिए लगाए गए ईवेंट अपडेट करें। लेकिन घटनाएं अपरिवर्तनीय होने के लिए हैं, इसलिए यह बहुत गंदा लगता है।
  • पहचान फ़ील्ड से छुटकारा पाने और इकाई कन्स्ट्रक्टर में उत्पन्न GUID का उपयोग करना। यह सबसे आसान हो सकता है लेकिन प्रदर्शन को हिट कर सकता है और अन्य चीजों को कठिन बना सकता है, जैसे डीबगिंग या पूछताछ (where id = 'B85E62C3-DC56-40C0-852A-49F759AC68FB', MIN, MAX इत्यादि)। मैं कई नमूना अनुप्रयोगों में यही देखता हूं।
  • हाइब्रिड दृष्टिकोण - अकेले पहचान छोड़ने के लिए और विदेशी कुंजी के लिए मुख्य रूप से इसका इस्तेमाल करते हैं और तेजी से मिलती है लेकिन अद्वितीय पहचानकर्ता है जिसके द्वारा मैं आवेदन में रिपोजिटरी से संस्थाओं खींच के रूप में GUID का उपयोग करें।
+3

घटना में इकाई के लिए एक संदर्भ शामिल न करें। सहेजने के बाद आईडी को ठीक करना ठीक है। इसे प्रकाशन पर अपरिवर्तनीय माना जाना चाहिए। हालांकि अगर आप घटना के उत्पादन के संदर्भ में रीट्रीज़ की अनुमति देने जा रहे हैं तो यह परेशानी हो सकती है।बाहर से आईडी को असाइन करने में मूल्य है, मुझे लगता है कि यह एक डिफ़ॉल्ट रणनीति होनी चाहिए। तो दोनों GUIDs और हाइब्रिड दृष्टिकोण का उपयोग कर काम कर सकते हैं। एक अन्य दृष्टिकोण कुछ हिलो तंत्र या हिमपात की तरह कुछ हो सकता है। –

+0

क्या आप हिलो और हिमपात का विस्तार कर सकते हैं? – Pein

+0

http://nhforge.org/blogs/nhibernate/archive/2009/03/20/nhibernate-poid-generators-revealed.aspx और http://engineering.twitter.com/2010/06/announcing-snowflake.html –

उत्तर

9

व्यक्तिगत रूप से मुझे अद्वितीय पहचानकर्ताओं के लिए GUID पसंद है, खासकर बहु-उपयोगकर्ता, वितरित वातावरण जहां संख्यात्मक आईडी समस्याएं पैदा करते हैं। इस प्रकार, मैं डेटाबेस उत्पन्न पहचान कॉलम/गुणों का कभी भी उपयोग नहीं करता हूं और यह समस्या दूर हो जाती है।

उस से छोटा, चूंकि आप सीक्यूआरएस का पालन कर रहे हैं, तो निस्संदेह एक CreateSomethingCommand और संबंधित CreateSomethingCommandHandler है जो वास्तव में नया उदाहरण बनाने के लिए आवश्यक चरणों को पूरा करता है और भंडार का उपयोग करके नई वस्तु को जारी रखता है (संदर्भ के माध्यम से। सेव चेंज)। मैं डोमेन ऑब्जेक्ट की बजाय यहां कुछ कथित घटनाएं बढ़ाऊंगा।

एक के लिए, यह आपकी समस्या नहीं सुलझती क्योंकि आदेश हैंडलर, पूरा करने के लिए डेटाबेस कार्रवाई के लिए प्रतीक्षा पहचान मूल्य बाहर खींच, वस्तु अद्यतन कर सकते हैं तो स्थिति में पहचान गुजरती हैं। लेकिन, सबसे महत्वपूर्ण बात यह है कि ऑब्जेक्ट 'बनाई गई' वस्तु के ठीक सवाल का भी पता चलता है?

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

तो, मेरी सिफारिश कमांड हैंडलर से ईवेंट को उठाना है। (नोट: अगर आप GUID पहचानकर्ता के लिए स्विच, मैं इस दृष्टिकोण का पालन करना होगा, क्योंकि आप कंस्ट्रक्टर्स से घटनाओं उठाना कभी नहीं करना चाहिए।)

+5

"तो, मेरी सिफारिश कमांड हैंडलर से ईवेंट को बढ़ाने के लिए है" => घटनाओं को डोमेन मॉडल का हिस्सा लेना चाहिए। एक गरीब कन्स्ट्रक्टर के बजाय, अर्थ बढ़ाने के लिए, मैं एक स्थिर कारखाना बनाउंगा: सफलता के मामले में घटना को 'बनाना' बनाना। – Mik378

+0

"एक के लिए, यह आपकी समस्या नहीं सुलझती क्योंकि आदेश हैंडलर, पूरा बाहर खींच पहचान मूल्य के लिए डेटाबेस ऑपरेशन के लिए इंतजार कर सकते हैं" - क्या हुआ अगर समय समाप्ति somewere उठता: वस्तु बनाई गई हैं, लेकिन आदेश हैंडलर एक अपवाद फेंकता है? सादगी के लिए, मैं कमांड हैंडलर को यूओडब्ल्यू के रूप में कार्यान्वित करना चाहता हूं। ऐसे मामले में आपको पहचान आईडी फ़ील्ड के रूप में इकाई आईडी के बजाय ग्रिड का उपयोग इकाई आईडी के रूप में करना होगा। –