जवाबों:
रिपॉजिटरी लेयर आपको डेटा के उपयोग पर अतिरिक्त स्तर प्रदान करता है। लिखने के बजाय
var context = new DatabaseContext();
return CreateObjectQuery<Type>().Where(t => t.ID == param).First();
डेटाबेस से एकल आइटम प्राप्त करने के लिए, आप रिपॉजिटरी इंटरफ़ेस का उपयोग करते हैं
public interface IRepository<T>
{
IQueryable<T> List();
bool Create(T item);
bool Delete(int id);
T Get(int id);
bool SaveChanges();
}
और कॉल करें Get(id)
। रिपोजिटरी परत बुनियादी सीआरयूडी ऑपरेशन को उजागर करती है ।
सेवा परत व्यावसायिक तर्क को उजागर करती है, जो भंडार का उपयोग करती है। उदाहरण सेवा की तरह लग सकता है:
public interface IUserService
{
User GetByUserName(string userName);
string GetUserNameByEmail(string email);
bool EditBasicUserData(User user);
User GetUserByID(int id);
bool DeleteUser(int id);
IQueryable<User> ListUsers();
bool ChangePassword(string userName, string newPassword);
bool SendPasswordReminder(string userName);
bool RegisterNewUser(RegisterNewUserModel model);
}
जबकि List()
रिपॉजिटरी का तरीका सभी यूजर्स का है, ListUsers()
IUserService की ही वापसी हो सकती है, यूजर की पहुंच है।
ASP.NET MVC + EF + SQL सर्वर में, मेरे पास संचार का यह प्रवाह है:
दृश्य <- नियंत्रक -> सेवा परत -> रिपॉजिटरी परत -> ईएफ -> एसक्यूएल सर्वर
सेवा परत -> रिपॉजिटरी परत -> ईएफ यह भाग मॉडल पर संचालित होता है।
दृश्य <- नियंत्रक -> सेवा परत यह भाग दृश्य मॉडलों पर संचालित होता है।
संपादित करें:
के लिए प्रवाह का उदाहरण / आदेश / ByClient / 5 (हम विशिष्ट ग्राहक के लिए आदेश देखना चाहते हैं):
public class OrderController
{
private IOrderService _orderService;
public OrderController(IOrderService orderService)
{
_orderService = orderService; // injected by IOC container
}
public ActionResult ByClient(int id)
{
var model = _orderService.GetByClient(id);
return View(model);
}
}
यह ऑर्डर सेवा के लिए इंटरफ़ेस है:
public interface IOrderService
{
OrdersByClientViewModel GetByClient(int id);
}
यह इंटरफ़ेस दृश्य मॉडल लौटाता है:
public class OrdersByClientViewModel
{
CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used
IEnumerable<OrderViewModel> Orders { get; set; }
}
यह इंटरफ़ेस कार्यान्वयन है। यह दृश्य मॉडल बनाने के लिए मॉडल कक्षाओं और रिपॉजिटरी का उपयोग करता है:
public class OrderService : IOrderService
{
IRepository<Client> _clientRepository;
public OrderService(IRepository<Client> clientRepository)
{
_clientRepository = clientRepository; //injected
}
public OrdersByClientViewModel GetByClient(int id)
{
return _clientRepository.Get(id).Select(c =>
new OrdersByClientViewModel
{
Cient = new ClientViewModel { ...init with values from c...}
Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...}
}
);
}
}
IRepository<>
करने के लिए GenericRepository<>
अपने आईओसी पुस्तकालय में। यह उत्तर बहुत पुराना है। मुझे लगता है कि सबसे अच्छा समाधान सभी रिपॉजिटरी को एक वर्ग में संयोजित करना है UnitOfWork
। इसमें हर प्रकार का भंडार और एक विधि कहा जाना चाहिए SaveChanges
। सभी रिपॉजिटरी को एक ईएफ संदर्भ साझा करना चाहिए।
जैसा कि कार्नोटॉरस ने कहा कि भंडार डेटा से आपके व्यवसाय की वस्तुओं के लिए आपके डेटा को मैप करने के लिए रिपॉजिटरी जिम्मेदार है। यह डेटा को पढ़ने और लिखने के तरीके को संभालना चाहिए (हटाएं, अपडेट करें) से और संग्रहण तक।
दूसरी ओर सर्विस लेयर का उद्देश्य कोड के पुन: उपयोग और चिंताओं के पृथक्करण को बढ़ावा देने के लिए व्यापार तर्क को एक ही स्थान पर संलग्न करना है। एस्पेक्ट एमवीसी साइटों के निर्माण के दौरान आमतौर पर व्यवहार में मेरे लिए इसका मतलब यह है कि मेरे पास यह संरचना है
[नियंत्रक] कॉल [सेवा (ओं)] जो कॉल [रिपॉजिटरी (ies)]
एक सिद्धांत जो मैंने उपयोगी पाया है, वह है कि लॉजिक को कम से कम कंट्रोलर्स और रिपॉजिटरी में रखना।
नियंत्रकों में यह है क्योंकि यह मुझे DRY रखने में मदद करता है। यह बहुत सामान्य है कि मुझे उसी फ़िल्टरिंग या तर्क का उपयोग कहीं और करने की आवश्यकता है और यदि मैंने इसे नियंत्रक में रखा है तो मैं इसका पुन: उपयोग नहीं कर सकता।
रिपॉजिटरी में यह इसलिए है क्योंकि मैं अपने स्टोरेज (या ओआरएम) को बदलने में सक्षम होना चाहता हूं जब कुछ बेहतर होता है। और अगर मेरे पास रिपॉजिटरी में तर्क है तो मुझे रिपॉजिटरी बदलने पर इस लॉजिक को फिर से लिखना होगा। यदि मेरी रिपॉजिटरी केवल IQueryable लौटाती है और सेवा दूसरी तरफ फ़िल्टरिंग करती है, तो मुझे केवल मैपिंग को बदलने की आवश्यकता होगी।
उदाहरण के लिए मैंने हाल ही में अपने कई Linq-To-Sql रिपॉजिटरी को EF4 के साथ बदल दिया और उन लोगों को जहां मैं इस सिद्धांत के लिए सही था, कुछ ही मिनटों में बदल सकते थे। जहां मेरे पास कुछ तर्क थे, यह बजाय घंटे की बात थी।
onBeforeBuildBrowseQuery
जा सकती है और क्वेरी को बदलने के लिए क्वेरी बिल्डर का उपयोग कर सकते हैं।
स्वीकृत उत्तर (और सैकड़ों बार उत्कीर्ण) का एक प्रमुख दोष है। मैं इस टिप्पणी में इंगित करना चाहता था, लेकिन यह सिर्फ 30 टिप्पणियों में नीचे दफन हो जाएगा इसलिए यहाँ इंगित करता है।
मैंने एक एंटरप्राइज़ एप्लिकेशन लिया जो उस तरह से बनाया गया था और मेरी प्रारंभिक प्रतिक्रिया WTH थी ? सेवा परत में ViewModels? मैं अधिवेशन को बदलना नहीं चाहता था क्योंकि विकास के वर्षों में यह चला गया था इसलिए मैंने ViewModels को वापस करना जारी रखा। लड़का यह दुःस्वप्न में बदल गया जब हमने WPF का उपयोग शुरू किया। हम (देवों की टीम) हमेशा कह रहे थे: कौन सा व्यूमॉडल? वास्तविक एक (जिसे हमने WPF के लिए लिखा था) या सेवाएं एक? वे एक वेब एप्लिकेशन के लिए लिखे गए थे और यहां तक कि यूआई में संपादन को अक्षम करने के लिए IsReadOnly ध्वज था । प्रमुख, प्रमुख दोष और सभी एक शब्द के कारण: ViewModel !!
इससे पहले कि आप वही गलती करें, ऊपर मेरी कहानी के अलावा कुछ और कारण दिए गए हैं:
सेवा स्तर से एक ViewModel लौटना एक बहुत बड़ी संख्या है। यह कहने जैसा है:
यदि आप इन सेवाओं का उपयोग करना चाहते हैं तो आप बेहतर तरीके से MVVM का उपयोग कर सकते हैं और यहाँ ViewModel है जिसका आपको उपयोग करने की आवश्यकता है। आउच!
सेवाएं यह धारणा बना रही हैं कि उन्हें कहीं यूआई में प्रदर्शित किया जाएगा। यदि यह गैर-यूआई एप्लिकेशन जैसे कि वेब सेवाओं या विंडोज़ सेवाओं द्वारा उपयोग किया जाता है तो क्या होगा?
यह भी एक वास्तविक ViewModel नहीं है। एक वास्तविक ViewModel में अवलोकनशीलता, आज्ञाएं आदि हैं जो एक बुरे नाम के साथ सिर्फ एक POCO है। (नाम क्यों मायने रखता है के लिए ऊपर मेरी कहानी देखें।)
खपत आवेदन बेहतर एक प्रस्तुति परत हो (ViewModels इस परत द्वारा उपयोग किया जाता है) और यह C # को बेहतर ढंग से समझता है। एक और आउच!
कृपया, ऐसा मत करो!
आमतौर पर एक रिपॉजिटरी का उपयोग आपकी संस्थाओं को आबाद करने के लिए मचान के रूप में किया जाता है - एक सेवा परत बाहर जाएगी और एक अनुरोध का स्रोत होगा। यह संभावना है कि आप अपनी सेवा परत के तहत एक भंडार रखेंगे।
डेटाबेस तक पहुँचने के लिए रिपॉजिटरी लेयर को लागू किया जाता है और डेटाबेस पर CRUD के संचालन को बढ़ाने में मदद करता है। जबकि एक सर्विस लेयर में एप्लिकेशन के व्यावसायिक तर्क होते हैं और डेटाबेस से जुड़े कुछ लॉजिक को लागू करने के लिए रिपॉजिटरी लेयर का उपयोग कर सकते हैं। एक आवेदन में, एक अलग रिपॉजिटरी परत और सेवा परत होना बेहतर है। अलग रिपॉजिटरी और सर्विस लेयर्स होने से कोड अधिक माड्यूलर हो जाता है और डेटाबेस को बिजनेस लॉजिक से अलग कर देता है।