नियंत्रक के लिए एक रिपॉजिटरी को सीधे कॉल करना बुरा नहीं है। एक "सेवा" सिर्फ एक और उपकरण है, इसलिए इसका उपयोग करें जहां यह समझ में आता है।
निकोलाईडेंट ने टिप्पणी की:
... सही आवेदन के लिए सही पैटर्न चुनें। मैं क्या कहूंगा कि आपको अपने आवेदन को सुसंगत बनाना चाहिए।
मुझे नहीं लगता कि संगति सबसे महत्वपूर्ण पहलू है। एक "सेवा" वर्ग का मतलब कुछ उच्च स्तर के तर्क को बदलना है, इसलिए नियंत्रक को इसे लागू करने की आवश्यकता नहीं है। यदि किसी दिए गए ऑपरेशन के लिए "उच्च स्तरीय तर्क" की आवश्यकता नहीं है, तो सीधे भंडार पर जाएं।
चिंताओं और परीक्षण की अच्छी पृथक्करण को बढ़ावा देने के लिए, रिपॉजिटरी एक निर्भरता होनी चाहिए जिसे आप एक निर्माता के माध्यम से सेवा में इंजेक्ट करते हैं:
IFooRepository repository = new FooRepository();
FooService service = new FooService(repository);
service.DoSomething(...);
यदि डेटाबेस में रिकॉर्ड की खोज करने के लिए किसी प्रकार के मानकीकृत क्वेरी की आवश्यकता होती है, तो सेवा वर्ग आपके दृश्य मॉडल में लेने और फिर रिपॉजिटरी द्वारा निष्पादित क्वेरी का निर्माण करने के लिए एक अच्छी जगह हो सकती है।
इसी तरह, यदि आपके पास फ़ॉर्म के लिए एक जटिल दृश्य मॉडल है, तो एक सेवा वर्ग आपके डोमेन मॉडल / एंटिटीज़ पर कॉल करके विधियों को बनाने, अपडेट करने और हटाने के तर्क को अतिक्रमण कर सकता है, फिर एक रिपॉजिटरी का उपयोग करके उन्हें जारी रख सकता है।
विपरीत दिशा में जा रहे हैं, यदि आपके नियंत्रक को इसकी आईडी द्वारा एक रिकॉर्ड प्राप्त करने की आवश्यकता है, तो इसके लिए एक सेवा ऑब्जेक्ट को सौंपना एक स्लेजहेमर के साथ एक थंबटैक को मारने की तरह है - यह आपकी ज़रूरत से अधिक तरीका है।
मैंने पाया है कि लेन-देन, या कार्य वस्तु की एक इकाई को संभालने के लिए नियंत्रक सबसे अच्छी स्थिति में है । नियंत्रक या यूनिट ऑफ़ वर्क ऑब्जेक्ट तब जटिल परिचालनों के लिए सेवा वस्तुओं को सौंपता है, या सीधे सरल संचालन के लिए रिपॉजिटरी में जाता है (जैसे आईडी द्वारा रिकॉर्ड खोजना)।
public class ShoppingCartsController : Controller
{
[HttpPost]
public ActionResult Edit(int id, ShoppingCartForm model)
{
// Controller initiates a database session and transaction
using (IStoreContext store = new StoreContext())
{
// Controller goes directly to a repository to find a record by Id
ShoppingCart cart = store.ShoppingCarts.Find(id);
// Controller creates the service, and passes the repository and/or
// the current transaction
ShoppingCartService service = new ShoppingCartService(store.ShoppingCarts);
if (cart == null)
return HttpNotFound();
if (ModelState.IsValid)
{
// Controller delegates to a service object to manipulate the
// Domain Model (ShoppingCart)
service.UpdateShoppingCart(model, cart);
// Controller decides to commit changes
store.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
return View(model);
}
}
}
}
मुझे लगता है कि सेवाओं का मिश्रण और रिपॉजिटरी के साथ सीधे काम करना पूरी तरह स्वीकार्य है। यदि आपको आवश्यकता महसूस हुई तो आप कार्य की इकाई में लेनदेन को आगे बढ़ा सकते हैं।
जिम्मेदारियों का टूटना इस तरह होता है:
- नियंत्रक अनुप्रयोग के प्रवाह को नियंत्रित करता है
- अगर शॉपिंग कार्ट डेटाबेस में नहीं है तो "404 नहीं मिला"
- सत्यापन विफल होने पर सत्यापन संदेशों के साथ फ़ॉर्म को फिर से प्रस्तुत करता है
- खरीदारी की टोकरी बचाता है अगर सब कुछ बाहर की जाँच करता है
- नियंत्रक आपके डोमेन मॉडल (या संस्थाओं) पर व्यावसायिक तर्क को निष्पादित करने के लिए एक सेवा वर्ग को दर्शाता है। सेवा वस्तुओं को व्यावसायिक तर्क को लागू नहीं करना चाहिए ! वे व्यापारिक तर्क को अंजाम देते हैं।
- नियंत्रक सीधे संचालन के लिए रिपॉजिटरी में सीधे प्रतिनिधि रख सकते हैं
- सेवा ऑब्जेक्ट दृश्य मॉडल में डेटा लेते हैं, और व्यावसायिक तर्क निष्पादित करने के लिए डोमेन मॉडल को सौंपते हैं (उदाहरण के लिए रिपॉजिटरी पर विधियों को कॉल करने से पहले डोमेन ऑब्जेक्ट पर सेवा ऑब्जेक्ट कॉल विधि)
- सेवा वस्तुएँ डेटा दृढ़ता के लिए रिपॉजिटरी को सौंपती हैं
- नियंत्रकों को या तो होना चाहिए:
- लेन-देन के जीवनकाल को प्रबंधित करें, या
- लेन-देन के जीवनकाल को प्रबंधित करने के लिए कार्य ऑब्जेक्ट की एक इकाई बनाएँ