উত্তর:
সংগ্রহস্থল স্তর আপনাকে ডেটা অ্যাক্সেসের জন্য বিমূর্ততার অতিরিক্ত স্তর দেয়। লেখার বদলে
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 একমাত্র বেশী আসতে পারে, ব্যবহারকারীকে অ্যাক্সেস আছে।
এএসপি.নেট এমভিসি + ইএফ + এসকিউএল সার্ভারে আমার এই যোগাযোগের প্রবাহ রয়েছে:
দর্শন <- কন্ট্রোলার -> পরিষেবা স্তর -> সংগ্রহস্থল স্তর -> EF -> এসকিউএল সার্ভার
পরিষেবা স্তর -> সংগ্রহস্থল স্তর -> EF এই অংশটি মডেলগুলিতে পরিচালনা করে।
ভিউ <- কন্ট্রোলার -> পরিষেবা স্তর এই অংশটি ভিউ মডেলগুলিতে কাজ করে।
সম্পাদনা করুন:
/ অর্ডার / বাইক্লায়েন্ট / 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
। সমস্ত সংগ্রহস্থলের একটি EF প্রসঙ্গ শেয়ার করা উচিত।
কার্নোটৌরাস বলেছিলেন যে সঞ্চয়ী বিন্যাস থেকে আপনার ব্যবসায়িক অবজেক্টগুলিতে আপনার ডেটা ম্যাপ করার জন্য এই সংগ্রহস্থলটি দায়বদ্ধ। স্টোরেজ থেকে এবং স্টোরেজে কীভাবে ডেটা পড়তে এবং লিখতে হয় (মুছুন, আপডেটও করুন) উভয়ই এটি পরিচালনা করতে হবে।
অন্যদিকে পরিষেবা স্তরটির উদ্দেশ্য হ'ল কোড পুনরায় ব্যবহার এবং উদ্বেগের পৃথকীকরণের প্রচারের জন্য ব্যবসায়ের যুক্তিগুলিকে একক স্থানে সজ্জিত করা। Asp.net এমভিসি সাইটগুলি তৈরি করার সময় এটি অনুশীলনে আমার পক্ষে সাধারণত যা বোঝায় তা হ'ল আমার এই কাঠামোটি রয়েছে
[কন্ট্রোলার] [পরিষেবা (গুলি) কে কল করে যাকে [ভান্ডার (আইস)] বলে
আমি যে নীতিটি দরকারী বলে মনে করেছি তা হ'ল নিয়ন্ত্রক এবং সংগ্রহস্থলগুলিতে সর্বনিম্ন লজিক রাখা।
নিয়ন্ত্রকদের মধ্যে এটি কারণ এটি আমাকে DRY রাখতে সহায়তা করে। এটি খুব সাধারণ যে আমার অন্য কোথাও একই ফিল্টারিং বা যুক্তি ব্যবহার করা দরকার এবং যদি আমি এটি নিয়ামকটিতে রাখি তবে আমি এটি পুনরায় ব্যবহার করতে পারি না।
ভান্ডারগুলিতে এটি কারণ কারণ যখন আরও ভাল কিছু আসে তখন আমি আমার স্টোরেজ (বা ওআরএম) প্রতিস্থাপন করতে সক্ষম হতে চাই। এবং আমার যদি ভাণ্ডারটিতে যুক্তি থাকে তবে আমি যখন সংগ্রহশালা পরিবর্তন করি তখন এই যুক্তিটি পুনরায় লিখতে হবে। যদি আমার সংগ্রহস্থলটি কেবলমাত্র আইকিউয়ারেবলকে ফিরিয়ে দেয় এবং পরিষেবা অন্যদিকে ফিল্টারিং করে তবে আমার কেবল ম্যাপিংগুলি প্রতিস্থাপন করতে হবে।
উদাহরণস্বরূপ আমি সম্প্রতি আমার লিঙ্ক-টু-এসকিএল সংগ্রহস্থলগুলি বেশ কয়েকটি ইএফ 4 এর সাথে প্রতিস্থাপন করেছি এবং আমি যেখানে এই নীতিতে সত্যবাদী ছিলাম তারা কয়েক মিনিটের ব্যবধানে প্রতিস্থাপন করতে পারে। আমার যেখানে কিছুটা যুক্তি ছিল তা পরিবর্তে কয়েক ঘন্টার ব্যাপার ছিল।
onBeforeBuildBrowseQuery
কোথাও পরিবর্তনের জন্য কোয়েরি বিল্ডারকে ব্যবহারের মতো পদ্ধতির মাধ্যমে সংগ্রহস্থলগুলির সাথে যোগাযোগ করে।
গৃহীত উত্তরের (এবং শতবার সময় বাড়িয়ে তোলা) একটি বড় ত্রুটি রয়েছে। আমি মন্তব্যে এটি উল্লেখ করতে চেয়েছিলাম তবে এটি কেবল এখানে এখানে উল্লেখ করা 30 টি মন্তব্যে সমাহিত হবে।
আমি একটি এন্টারপ্রাইজ অ্যাপ্লিকেশন গ্রহণ করেছি যা সেভাবে নির্মিত হয়েছিল এবং আমার প্রাথমিক প্রতিক্রিয়াটি ডাব্লুটিএইচ ? পরিষেবা স্তরে ভিউমোডেলস? আমি কনভেনশনটি পরিবর্তন করতে চাইনি কারণ বছরগুলিতে বিকাশ ঘটেছিল তাই আমি ভিউমোডেলগুলি ফেরত দিয়ে চলেছি। ছেলে যখন আমরা ডাব্লুপিএফ ব্যবহার শুরু করি তখন এটি একটি দুঃস্বপ্নে পরিণত হয়েছিল। আমরা (দেবগণের দল) সবসময় বলছিলাম: কোন ভিউমোডেল? আসলটি (আমরা ডাব্লুপিএফের জন্য লিখেছিলাম) নাকি পরিষেবাগুলি? এগুলি একটি ওয়েব অ্যাপ্লিকেশনের জন্য লেখা হয়েছিল এবং এমনকি ইউআইতে সম্পাদনা অক্ষম করার জন্য ইস্রাডইনলি পতাকাও ছিল । প্রধান, প্রধান ত্রুটি এবং সমস্ত এক শব্দের কারণে: ভিউমোডেল !!
আপনি একই ভুল করার আগে, এখানে আমার গল্পটি ছাড়াও আরও কয়েকটি কারণ রয়েছে:
পরিষেবা স্তর থেকে একটি ভিউমোডেল ফিরে আসা একটি বিশাল সংখ্যা নয়। এটি বলার মতো:
আপনি যদি এই পরিষেবাগুলি ব্যবহার করতে চান তবে আপনি আরও ভাল করে এমভিভিএম ব্যবহার করবেন এবং আপনার এখানে ব্যবহারের প্রয়োজন ভিউমোডেল। সেকি!
পরিষেবাগুলি ধারণাটি তৈরি করছে যে তারা কোথাও কোনও ইউআইতে প্রদর্শিত হবে। যদি এটি কোনও ইউআই অ্যাপ্লিকেশন যেমন ওয়েব পরিষেবাদি বা উইন্ডো পরিষেবাগুলির দ্বারা ব্যবহৃত হয় তবে কী হবে?
এটি সত্যিকারের ভিউমোডেলও নয়। একটি বাস্তব ভিউমোডেলের পর্যবেক্ষণ, কমান্ড ইত্যাদি রয়েছে That এটি একটি খারাপ নাম সহ একটি পোকো। (নামগুলি কেন গুরুত্বপূর্ণ তার জন্য আমার গল্পটি উপরে দেখুন))
গ্রাহক অ্যাপ্লিকেশনটি উপস্থাপনা স্তর হিসাবে ভাল হবে (ভিউমোডেলগুলি এই স্তরটি ব্যবহার করে) এবং এটি সি # আরও ভাল বোঝে। আরেকটি আউচ!
দয়া করে, এটা করবেন না!
আপনার সত্তাগুলি জনসাধারণের জন্য সাধারণত একটি সংগ্রহস্থল ভারা হিসাবে ব্যবহৃত হয় - একটি পরিষেবা স্তর বের হয়ে একটি অনুরোধ উত্স করে। সম্ভবত আপনি আপনার পরিষেবা স্তরের নীচে একটি সংগ্রহস্থল রাখবেন।
ডাটাবেস অ্যাক্সেস করতে রিপোজিটরি স্তর প্রয়োগ করা হয় এবং ডাটাবেসে সিআরইউডি অপারেশন প্রসারিত করতে সহায়তা করে। যেখানে কোনও পরিষেবা স্তর অ্যাপ্লিকেশনটির ব্যবসায়িক যুক্তি নিয়ে থাকে এবং ডাটাবেস জড়িত কিছু যুক্তি প্রয়োগ করতে রিপোজিটরি স্তরটি ব্যবহার করতে পারে। একটি অ্যাপ্লিকেশনটিতে, পৃথক সংগ্রহস্থল স্তর এবং পরিষেবা স্তর থাকা ভাল। পৃথক সংগ্রহস্থল এবং পরিষেবা স্তর থাকার কোডটিকে আরও মডুলার করে এবং ব্যবসায়িক যুক্তি থেকে ডাটাবেসটিকে ডিকুয়াল করে।