asp.net-mvc - उनल - विश्व का मानचित्र




POST कार्रवाई में डोमेन मॉडल पर वापस मॉडल को मानचित्र कैसे करें? (3)

आपको डोमेन पर व्यूमोडेल मैपिंग की आवश्यकता नहीं है क्योंकि आपका व्यूमोडेल डोमेन मॉडल से अधिक बनाया जा सकता है। स्क्रीन (ui) के लिए ऑप्टिमाइज़ किए गए व्यूमोडल्स और डोमेन मॉडल से अलग।

http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

व्यूमोडल्स का उपयोग करने और ऑटोमैपर का उपयोग करने पर इंटरनेट में पाया गया प्रत्येक आलेख "नियंत्रक -> देखें" दिशा मैपिंग के दिशानिर्देश देता है। आप सभी विशिष्ट सूची के साथ एक विशेष दृश्य मॉडल में एक डोमेन मॉडल लेते हैं और इसे दृश्य में पास करते हैं। यह स्पष्ट और ठीक है।
दृश्य में एक रूप है, और अंततः हम पोस्ट कार्रवाई में हैं। यहां सभी मॉडल बाइंडर्स [स्पष्ट रूप से] एक और दृश्य मॉडल के साथ दृश्य में आते हैं जो स्पष्ट रूप से बाध्यकारी और सत्यापन के लिए नामकरण सम्मेलनों के नाम पर मूल व्यू मॉडेल से संबंधित है।

आप इसे अपने डोमेन मॉडल में कैसे मैप करते हैं?

इसे एक सम्मिलित कार्रवाई करने दें, हम एक ही ऑटोमैपर का उपयोग कर सकते हैं। लेकिन क्या होगा यदि यह एक अद्यतन कार्रवाई थी? हमें रिपोजिटरी से हमारी डोमेन इकाई को पुनर्प्राप्त करना होगा, व्यूमोडेल के मानों के अनुसार इसकी गुणों को अपडेट करना होगा और रिपोजिटरी में सहेजना होगा।

अतिरिक्त 1 (फरवरी 2010 का 9वां): कभी-कभी, मॉडल की गुणों को असाइन करना पर्याप्त नहीं है। व्यू मॉडल के मूल्यों के अनुसार डोमेन मॉडल के खिलाफ कुछ कार्रवाई की जानी चाहिए। हां, डोमेन मॉडल पर कुछ तरीकों को बुलाया जाना चाहिए। शायद, एक प्रकार की अनुप्रयोग सेवा परत होनी चाहिए जो दृश्य मॉडल को संसाधित करने के लिए नियंत्रक और डोमेन के बीच है ...

इस कोड को व्यवस्थित करने के लिए और निम्नलिखित लक्ष्यों को प्राप्त करने के लिए इसे कहां रखा जाए?

  • नियंत्रकों को पतला रखें
  • सम्मान एसओसी अभ्यास
  • डोमेन-संचालित डिजाइन सिद्धांतों का पालन करें
  • सूखी हो
  • जारी ...

ऑटो ऑब्जेक्ट जैसे टूल्स का उपयोग मौजूदा ऑब्जेक्ट को स्रोत ऑब्जेक्ट से डेटा के साथ अपडेट करने के लिए किया जा सकता है। अद्यतन करने के लिए नियंत्रक कार्रवाई इस तरह दिख सकती है:

[HttpPost]
public ActionResult Update(MyViewModel viewModel)
{
    MyDataModel dataModel = this.DataRepository.GetMyData(viewModel.Id);
    Mapper<MyViewModel, MyDataModel>(viewModel, dataModel);
    this.Repostitory.SaveMyData(dataModel);
    return View(viewModel);
}

उपरोक्त स्निपेट में जो दिखाई देता है उसके अलावा:

  • मॉडल + सत्यापन देखने के लिए पोस्ट डेटा मॉडलबिंडर में किया जाता है (कस्टम बाइंडिंग के साथ बढ़ाया जा सकता है)
  • त्रुटि प्रबंधन (यानी रिपोजिटरी द्वारा डेटा एक्सेस अपवाद फेंकता है) [हैंडलरर] फ़िल्टर द्वारा किया जा सकता है

नियंत्रक कार्रवाई बहुत पतली है और चिंताओं को अलग किया जाता है: मैपिंग मुद्दों को ऑटोमैपर कॉन्फ़िगरेशन में संबोधित किया जाता है, मॉडलबिंडर द्वारा सत्यापन किया जाता है और रिपोजिटरी द्वारा डेटा एक्सेस किया जाता है।


मैं कहना चाहूंगा कि क्लाइंट इंटरैक्शन के दोनों दिशाओं के लिए आप व्यूमोडेल शब्द का पुन: उपयोग करते हैं। यदि आपने जंगली में पर्याप्त एएसपी.नेट एमवीसी कोड पढ़ लिया है तो आपने शायद व्यूमोडेल और एडिटमोडेल के बीच भेद देखा है। मुझे लगता है कि यह महत्वपूर्ण है।

एक व्यूमोडेल दृश्य प्रस्तुत करने के लिए आवश्यक सभी जानकारी का प्रतिनिधित्व करता है। इसमें डेटा को शामिल किया जा सकता है जो स्थैतिक गैर-इंटरैक्टिव स्थानों में प्रदान किया जाता है और यह भी सुनिश्चित करने के लिए कि वास्तव में प्रस्तुत करने के लिए चेक करने के लिए डेटा को पूरी तरह से प्रस्तुत किया जा सकता है। एक नियंत्रक प्राप्त करें आमतौर पर व्यूमोडेल को अपने दृश्य के लिए पैकेजिंग के लिए ज़िम्मेदार होता है।

एक एडिटमोडेल (या शायद एक एक्शनमोडेल) उस पोस्ट को उस क्रिया को करने के लिए आवश्यक डेटा का प्रतिनिधित्व करता है जिसे उपयोगकर्ता उस पोस्ट के लिए करना चाहता था। तो एक एडिटमोडेल वास्तव में एक क्रिया का वर्णन करने की कोशिश कर रहा है। यह संभवतः व्यूमोडेल से कुछ डेटा बहिष्कृत करेगा और हालांकि मुझे लगता है कि यह महसूस करना महत्वपूर्ण है कि वे वास्तव में अलग हैं।

एक विचार

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

एक अन्य विचार

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

अनिवार्य रूप से जब उपयोगकर्ता आपके द्वारा प्रस्तुत की गई स्क्रीन पर कार्रवाइयां करता है, तो जावास्क्रिप्ट क्रिया वस्तुओं की एक सूची बनाना शुरू कर देगा। एक उदाहरण संभवतः उपयोगकर्ता एक कर्मचारी सूचना स्क्रीन पर है। वे अंतिम नाम अपडेट करते हैं और एक नया पता जोड़ते हैं क्योंकि कर्मचारी हाल ही में विवाहित है। कवर के तहत यह एक सूची में ChangeEmployeeName और AddEmployeeMailingAddress ऑब्जेक्ट्स AddEmployeeMailingAddress । उपयोगकर्ता परिवर्तनों को करने के लिए 'सहेजें' पर क्लिक करता है और आप दो ऑब्जेक्ट्स की सूची सबमिट करते हैं, प्रत्येक में प्रत्येक क्रिया को करने के लिए आवश्यक जानकारी होती है।

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

तो शायद इस तरह कुछ ऐसा सर्वर पक्ष पर महसूस हो जाता है:

public interface IUserAction<TModel>
{
     long ModelId { get; set; }
     IEnumerable<string> Validate(TModel model);
     void Complete(TModel model);
}

[Transaction] //just assuming some sort of 2-tier with transactions handled by filter
public ActionResult Save(IEnumerable<IUserAction<Employee>> actions)
{
     var errors = new List<string>();
     foreach( var action in actions ) 
     {
         // relying on ORM's identity map to prevent multiple database hits
         var employee = _employeeRepository.Get(action.ModelId);
         errors.AddRange(action.Validate(employee));
     }

     // handle error cases possibly rendering view with them

     foreach( var action in editModel.UserActions )
     {
         var employee = _employeeRepository.Get(action.ModelId);
         action.Complete(employee);
         // against relying on ORMs ability to properly generate SQL and batch changes
         _employeeRepository.Update(employee);
     }

     // render the success view
}

यह वास्तव में पोस्टिंग बैक एक्शन को काफी सामान्य बनाता है क्योंकि आप अपने मॉडलबिंडर पर भरोसा कर रहे हैं ताकि आपको सही IUserAction इंस्टेंस और आपके IUserAction इंस्टेंस को सही तर्क स्वयं करने के लिए या (अधिक संभावना) जानकारी के साथ मॉडल में कॉल करने के लिए किया जा सके।

यदि आप 3 स्तर के माहौल में थे, तो IUserAction को सीमा पार शॉट करने के लिए सरल डीटीओ बनाया जा सकता था और ऐप परत पर एक समान विधि में किया गया था। आप उस परत को कैसे करते हैं इस पर निर्भर करते हुए इसे बहुत आसानी से विभाजित किया जा सकता है और फिर भी एक लेनदेन में रहता है (दिमाग में क्या आता है अगाथा के अनुरोध / प्रतिक्रिया और डीआई और एनएचबेर्नेट के पहचान मानचित्र का लाभ लेना)।

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





separation-of-concerns