একটি কাজের সাক্ষাত্কারের সময়, আমাকে ব্যাখ্যা করতে জিজ্ঞাসা করা হয়েছিল কেন সত্তা ফ্রেমওয়ার্কের মতো ওআরএম এর সাথে কাজ করার জন্য সংগ্রহস্থল প্যাটার্নটি ভাল প্যাটার্ন নয়। কেন এই ক্ষেত্রে?
একটি কাজের সাক্ষাত্কারের সময়, আমাকে ব্যাখ্যা করতে জিজ্ঞাসা করা হয়েছিল কেন সত্তা ফ্রেমওয়ার্কের মতো ওআরএম এর সাথে কাজ করার জন্য সংগ্রহস্থল প্যাটার্নটি ভাল প্যাটার্ন নয়। কেন এই ক্ষেত্রে?
উত্তর:
সত্ত্বা ফ্রেমওয়ার্কের সাথে কাজ না করার জন্য সংগ্রহস্থল প্যাটার্নের কোনও কারণ আমি দেখতে পাচ্ছি না। সংগ্রহস্থল প্যাটার্ন হ'ল একটি বিমূর্ত স্তর যা আপনি আপনার ডেটা অ্যাক্সেস স্তরকে রেখেছিলেন। আপনার ডেটা অ্যাক্সেস স্তরটি খাঁটি ADO.NET সঞ্চিত পদ্ধতি থেকে সত্ত্বা ফ্রেমওয়ার্ক বা একটি এক্সএমএল ফাইলের যে কোনও কিছু হতে পারে।
বৃহত সিস্টেমে, যেখানে আপনার বিভিন্ন উত্স (ডাটাবেস / এক্সএমএল / ওয়েব পরিষেবা) থেকে ডেটা আসে, সেখানে বিমূর্ত স্তর থাকা ভাল। সংগ্রহস্থল প্যাটার্ন এই পরিস্থিতিতে ভাল কাজ করে। আমি বিশ্বাস করি না যে পর্দার আড়ালে কী ঘটে তা আড়াল করার জন্য সত্তা ফ্রেমওয়ার্ক যথেষ্ট বিমূর্ততা।
আমি আমার ডেটা অ্যাক্সেস লেয়ার পদ্ধতি হিসাবে সত্ত্বা ফ্রেমওয়ার্ক সহ সংগ্রহস্থল প্যাটার্নটি ব্যবহার করেছি এবং এখনও কোনও সমস্যার মুখোমুখি হতে পারি না।
DbContext
একটি সংগ্রহস্থল সহ বিমূর্ত করার আরেকটি সুবিধা হ'ল ইউনিট-টেস্টাবিলিটি । আপনার কাছে আপনার IRepository
ইন্টারফেস থাকতে পারে যার সাথে দুটি বাস্তবায়ন রয়েছে, একটি (আসল রিপোজিটরি) যা DbContext
ডাটাবেসের সাথে কথা বলার জন্য ব্যবহার করে এবং দ্বিতীয়টি, FakeRepository
যা মেমোরি অবজেক্টস / উপহাসের ডেটা ফিরে আসতে পারে। এটি আপনার IRepository
ইউনিট-পরীক্ষামূলক করে তোলে , এইভাবে কোডের অন্যান্য অংশগুলি ব্যবহার করে IRepository
।
public interface IRepository
{
IEnumerable<CustomerDto> GetCustomers();
}
public EFRepository : IRepository
{
private YourDbContext db;
private EFRepository()
{
db = new YourDbContext();
}
public IEnumerable<CustomerDto> GetCustomers()
{
return db.Customers.Select(f=>new CustomerDto { Id=f.Id, Name =f.Name}).ToList();
}
}
public MockRepository : IRepository
{
public IEnumerable<CustomerDto> GetCustomers()
{
// to do : return a mock list of Customers
// Or you may even use a mocking framework like Moq
}
}
এখন ডিআই ব্যবহার করে আপনি বাস্তবায়ন পাবেন
public class SomeService
{
IRepository repo;
public SomeService(IRepository repo)
{
this.repo = repo;
}
public void SomeMethod()
{
//use this.repo as needed
}
}
সত্তা ফ্রেমওয়ার্কের সাথে সংগ্রহস্থল প্যাটার্নটি ব্যবহার না করার একক সেরা কারণ? সত্তা ফ্রেমওয়ার্ক ইতিমধ্যে একটি সংগ্রহস্থল প্যাটার্ন প্রয়োগ করে। DbContext
আপনার ইউওডাব্লু (কাজের ইউনিট) এবং প্রতিটি DbSet
হ'ল সংগ্রহস্থল। এর উপরে অন্য স্তর প্রয়োগ করা কেবলমাত্র অতিরিক্ত কাজ নয়, তবে রক্ষণাবেক্ষণকে আরও শক্ত করে তোলে।
প্যাটার্নের উদ্দেশ্য বুঝতে না পেরে লোকেরা নিদর্শনগুলি অনুসরণ করে । সংগ্রহস্থল প্যাটার্নের ক্ষেত্রে, উদ্দেশ্য হ'ল নিম্ন-স্তরের ডাটাবেস অনুসন্ধান যুক্তিটি বিমূর্ত করা। আপনার কোডে আসলে এসকিউএল স্টেটমেন্ট লেখার পুরানো দিনগুলিতে, সংগ্রহস্থল প্যাটার্নটি ছিল যে আপনার কোড বেস জুড়ে ছড়িয়ে ছিটিয়ে থাকা পৃথক পদ্ধতিগুলির মধ্যে থেকে এসকিউএলকে সরিয়ে নিয়ে এক জায়গায় স্থানীয়করণের উপায়। অ্যান্টিটি ফ্রেমওয়ার্ক, এনএইচবারনেট ইত্যাদির মতো একটি ওআরএম থাকা এই কোড বিমূর্ততার প্রতিস্থাপন , এবং যেমন, প্যাটার্নের প্রয়োজনীয়তার প্রয়োজনীয়তা উপেক্ষা করে।
তবে আপনার ওআরএম এর উপরে একটি বিমূর্ততা তৈরি করা খারাপ ধারণা নয়, কেবল ইউওডাব্লু / রিপোস্টিটরির মতো জটিল কিছু নয়। আমি একটি পরিষেবা প্যাটার্ন সহ যাব, যেখানে আপনি এমন একটি এপিআই তৈরি করেন যা আপনার অ্যাপ্লিকেশনটি অ্যান্টিটি ফ্রেমওয়ার্ক, এনএইচবারনেট বা কোনও ওয়েব এপিআই থেকে ডেটা আসছে কিনা তা জেনে বা যত্ন ছাড়াই ব্যবহার করতে পারে। এটি অনেক সহজ, আপনি যেভাবে আপনার অ্যাপ্লিকেশনটির প্রয়োজনীয় ডেটা ফেরত দেওয়ার জন্য কেবল আপনার পরিষেবা শ্রেণিতে পদ্ধতি যুক্ত করেন। উদাহরণস্বরূপ, আপনি যদি কোনও করণীয় অ্যাপটি লিখছিলেন, তবে আপনার কাছে এই সপ্তাহে প্রদত্ত আইটেমগুলি ফেরত দেওয়ার জন্য কোনও পরিষেবা কল থাকতে পারে এবং এখনও এটি সম্পন্ন হয়নি। আপনার সমস্ত অ্যাপ্লিকেশন জানেন যে এটি যদি এই তথ্য চায় তবে এটি সেই পদ্ধতিটিকে কল করে। সেই পদ্ধতির ভিতরে এবং সাধারণভাবে আপনার সেবার ভিতরে আপনি সত্ত্বা ফ্রেমওয়ার্ক বা আপনি যে কোনও কিছু ব্যবহার করছেন তার সাথে যোগাযোগ করেন। তারপরে, আপনি যদি পরে ওআরএম পরিবর্তন করতে চান বা কোনও ওয়েব এপিআই থেকে তথ্যটি টানেন,
এটি মনে হতে পারে যে এটি রিপোজিটরি প্যাটার্নটি ব্যবহারের জন্য একটি সম্ভাব্য যুক্তি, তবে এখানে মূল পার্থক্যটি হ'ল একটি পরিষেবা একটি পাতলা স্তর এবং এমন কোনও কিছু যা আপনি জিজ্ঞাসা অব্যাহত রাখার পরিবর্তে সম্পূর্ণ-বেকড ডেটা ফেরার দিকে তত্পর হন a সংগ্রহস্থল।
DbContext
(দেখুন: msdn.microsoft.com/en-us/data/dn314429.aspx )। এমনকি কম সংস্করণেও, আপনি বিদ্রূপযুক্তগুলির DbContext
সাথে একটি জাল- সদৃশ শ্রেণি ব্যবহার করতে পারেন DbSet
, যেহেতু DbSet
এটির স্থানটি প্রয়োগ করে IDbSet
।
আয়েন্দে রাহিয়েনের কাছ থেকে নেওয়া এখানে: আযাবের গর্তে আর্কিটেকচার: সংগ্রহশালার বিমূর্ত স্তরটির কুফল
আমি তার সিদ্ধান্তের সাথে একমত কিনা তা এখনও নিশ্চিত নই। এটি একটি ক্যাচ -২২ - একদিকে, যদি আমি কোয়েরি-সুনির্দিষ্ট ডেটা পুনরুদ্ধারের পদ্ধতিগুলি সহ টাইপ-নির্দিষ্ট ভাণ্ডারগুলিতে আমার ইএফ প্রসঙ্গে আবদ্ধ করি, তবে আমি আসলে আমার কোড (সাজানোর) পরীক্ষা করতে সক্ষম হয়েছি, যা সত্তার সাথে প্রায় অসম্ভব is একা ফ্রেমওয়ার্ক। অন্যদিকে, আমি সমৃদ্ধ অনুসন্ধান এবং সম্পর্কের শব্দার্থ রক্ষণাবেক্ষণের ক্ষমতাটি হারাতে পারি (তবে এই বৈশিষ্ট্যগুলিতে আমার সম্পূর্ণ অ্যাক্সেস থাকা সত্ত্বেও আমি সর্বদা মনে করি যে আমি ইএফ এর আশেপাশে ডিমের খোসায় হাঁটছি বা অন্য যে কোনও ওআরএম আমি বেছে নিতে পারি) , যেহেতু আমি কখনই জানি না যে এর আইকিউয়েরেবল বাস্তবায়ন কী কী পদ্ধতিগুলি সমর্থন করতে পারে বা সমর্থন করতে পারে না, এটি কোনও নেভিগেশন সম্পত্তি সংগ্রহকে আমার সৃষ্টি বা নিছক কোনও সমিতি হিসাবে ব্যাখ্যা করবে, এটি অলস বা আগ্রহী লোডে যাচ্ছে বা আদৌ লোড হবে না কিনা ডিফল্ট, ইত্যাদি, সুতরাং এটি আরও ভাল জন্য। জিরো-ইম্পিডেন্স অবজেক্ট-রিলেশনাল "ম্যাপিং" পৌরাণিক জীবের কিছু - সম্ভবত সে কারণেই সত্তা ফ্রেমওয়ার্কের সর্বশেষ প্রকাশটি "ম্যাজিক ইউনিকর্ন" এর নামকরণ করা হয়েছিল)।
তবে, কোয়েরি-নির্দিষ্ট ডেটা পুনরুদ্ধার পদ্ধতির মাধ্যমে আপনার সত্তাগুলি পুনরুদ্ধার করার অর্থ হ'ল আপনার ইউনিট পরীক্ষাগুলি এখন মূলত সাদা বাক্সের পরীক্ষা এবং আপনার এই বিষয়ে কোনও পছন্দ নেই, কারণ পরীক্ষার অধীনে ইউনিট কোন সংগ্রহস্থল পদ্ধতিতে চলেছে ঠিক আপনার অবশ্যই আগে থেকেই জেনে রাখা উচিত since এটি উপহাস করার জন্য কল করুন। আপনি এখনও ইন্টিগ্রেশন টেস্টগুলি না লিখে আপনি এখনও সত্যগুলি নিজেরাই পরীক্ষা করছেন না।
এগুলি এমন জটিল সমস্যা যাগুলির একটি জটিল সমাধানের প্রয়োজন। আপনি কেবল এটি ভান করে এটিকে ঠিক করতে পারবেন না যে আপনার সমস্ত সত্তা তাদের মধ্যে কোনও সম্পর্ক ছাড়াই আলাদা প্রকারের এবং এগুলির প্রত্যেককে তাদের নিজস্ব ভান্ডারে অ্যাটমাইজ করে। ভাল আপনি পারেন , কিন্তু এটি স্তন্যপান।
আপডেট: সত্তা ফ্রেমওয়ার্কের জন্য প্রচেষ্টা সরবরাহকারীর ব্যবহার করে আমি কিছুটা সাফল্য পেয়েছি । এফোর্ট হ'ল একটি মেমোরি সরবরাহকারী (ওপেন সোর্স) যা আপনাকে পরীক্ষায় EF ব্যবহার করতে দেয় ঠিক যেভাবে আপনি এটি ব্যবহার করতে পারবেন সত্যিকারের ডাটাবেসের বিরুদ্ধে। আমি এই সরবরাহকারীর ব্যবহারের জন্য কাজ করছি এই প্রকল্পের সমস্ত পরীক্ষার স্যুইচিংয়ের বিষয়টি বিবেচনা করছি, কারণ বিষয়গুলি এত সহজ করে তোলে বলে মনে হয়। আমি এখন পর্যন্ত এটিই একমাত্র সমাধান পেয়েছি যা আমি আগে যে সমস্যাগুলি ছড়িয়েছিলাম তার সমস্ত সমস্যার সমাধান করে। কেবলমাত্র পরীক্ষাটি শুরু করার সময় কিছুটা বিলম্ব হয় কারণ এটি মেমোরি ডাটাবেস তৈরি করে (এটি এটি করতে NMemory নামে অন্য একটি প্যাকেজ ব্যবহার করে) তবে আমি এটিকে আসল সমস্যা হিসাবে দেখছি না। একটি কোড প্রকল্প নিবন্ধ রয়েছে যা পরীক্ষার জন্য প্রচেষ্টা (বনাম এসকিউএল সিই) ব্যবহার করার বিষয়ে কথা বলে।
DbContext
। নির্বিশেষে, আপনি সর্বদা বিদ্রূপ করতে পারেন DbSet
, এবং এটি যাইহোক, সত্তা ফ্রেমওয়ার্কের মাংস। DbContext
আপনার DbSet
সম্পত্তি (রিপোজিটরিগুলি) এক জায়গায় (কাজের একক) রাখার জন্য একটি শ্রেণীর চেয়ে কিছুটা বেশি , বিশেষত একটি ইউনিট পরীক্ষার প্রসঙ্গে, যেখানে সমস্ত ডাটাবেস সূচনা এবং সংযোগ স্টাফের প্রয়োজন হয় না বা প্রয়োজন হয় না।
আপনি সম্ভবত এটি করার কারণটি হ'ল এটি কিছুটা অতিরিক্ত। সত্তা ফ্রেমওয়ার্ক আপনাকে কোডিং এবং কার্যকরী সুবিধার জন্য প্রচুর পরিমাণে সম্পদ দেয়, এজন্য আপনি এটি ব্যবহার করেন, আপনি যদি সেগুলি গ্রহণ করেন এবং যদি আপনি সেই সুবিধাগুলি দূরে সরিয়ে রাখছেন এমন কোনও ভাণ্ডার নকশায় এটি আবদ্ধ করেন, আপনি পাশাপাশি অন্য কোনও ডেটা অ্যাক্সেস স্তর ব্যবহার করতে পারেন।
তত্ত্বে আমি মনে করি এটি আরও সহজে পুনরায় ব্যবহারযোগ্য করে তোলার জন্য ডাটাবেস সংযোগের যুক্তিকে সজ্জিত করা বোধগম্য, তবে নীচের লিঙ্কটি যুক্তি হিসাবে দেখায়, আমাদের আধুনিক কাঠামোগুলি মূলত এখন এটির যত্ন নেবে।
ISessionFactory
এবং ISession
সহজেই উপহাসযোগ্য) এর পক্ষে সত্য DbContext
, তবে দুর্ভাগ্যক্রমে ... এটি এতটা সহজ নয় ...
সংগ্রহস্থল প্যাটার্নটি ব্যবহার করার একটি খুব ভাল কারণ হ'ল আপনার ব্যবসায়িক যুক্তি এবং / অথবা আপনার ইউআইকে সিস্টেম.ডাটা.এন্টিটি থেকে আলাদা করার অনুমতি দেওয়া। তিনি নকল বা মকস ব্যবহারের অনুমতি দিয়ে ইউনিট পরীক্ষায় আসল সুবিধা সহ এর অনেকগুলি সুবিধা রয়েছে।
আমাদের সদৃশ কিন্তু ভিন্ন সত্তা ফ্রেমওয়ার্ক DbContext দৃষ্টান্তগুলির সাথে সমস্যা হয়েছে যখন কোনও আইওসি পাত্রে নতুন () প্রকারের প্রতিলিপিগুলি (উদাহরণস্বরূপ একটি ব্যবহারকারীরপোসিট্রি এবং একটি গ্রুপ রেপোসটরি উদাহরণস্বরূপ যে প্রত্যেকে ডিবিসিএনটেক্সট থেকে নিজস্ব আইডিবিসেট কল করে) অনুরোধ অনুযায়ী একাধিক প্রসঙ্গ তৈরি করতে পারে (একটি এমভিসি / ওয়েব প্রসঙ্গে)।
বেশিরভাগ সময় এটি এখনও কাজ করে, তবে আপনি যখন তার উপরে একটি পরিষেবা স্তর যুক্ত করেন এবং সেই পরিষেবাগুলি ধরে নেওয়া হয় যে একটি প্রসঙ্গে তৈরি করা অবজেক্টগুলি অন্য প্রসঙ্গে নতুন অবজেক্টে শিশু সংগ্রহ হিসাবে যথাযথভাবে সংযুক্ত হবে, এটি কখনও কখনও ব্যর্থ হয় এবং কখনও কখনও হয় না ' টি কমিট গতির উপর নির্ভর করে।
ছোট প্রকল্পে সংগ্রহস্থল প্যাটার্ন চেষ্টা করার পরে আমি দৃ strongly়ভাবে এটি ব্যবহার না করার পরামর্শ দিচ্ছি; এটি আপনার সিস্টেমকে জটিল করে তোলে না, এবং উপহাসের উপাত্তগুলি দুঃস্বপ্ন বলে নয়, তবে আপনার পরীক্ষাটি অকেজো হয়ে যায় বলে নয় !!
উপহাসের তথ্য আপনাকে শিরোনাম ছাড়াই বিশদ যুক্ত করতে, ডাটাবেস সীমাবদ্ধতা লঙ্ঘনকারী রেকর্ড যুক্ত করতে এবং ডাটাবেসগুলি অপসারণ করতে অস্বীকার করবে এমন সত্তাগুলি সরিয়ে দেয়। বাস্তব বিশ্বে একটি একক আপডেট একাধিক সারণী, লগ, ইতিহাস, সংক্ষিপ্ত বিবরণ ইত্যাদির পাশাপাশি শেষ-সংশোধিত-তারিখের ক্ষেত্র, স্বয়ংক্রিয়ভাবে উত্পন্ন কী, গণিত ক্ষেত্রের মতো কলামগুলিকে প্রভাবিত করতে পারে।
সংক্ষেপে রিয়েল ডাটাবেসে আপনার পরীক্ষা চালিয়ে যাওয়া আপনাকে প্রকৃত ফলাফল দেয় এবং আপনি কেবল আপনার পরিষেবাদি এবং ইন্টারফেসগুলিই নয় তবে ডাটাবেসের আচরণও পরীক্ষা করতে পারেন। আপনার সঞ্চিত পদ্ধতিগুলি ডেটা সহ সঠিক কাজ করে কিনা, প্রত্যাশিত ফলাফলটি প্রত্যাবর্তন করতে পারে, বা আপনি যে রেকর্ডটি মুছে ফেলার জন্য পাঠিয়েছিলেন তা সত্যিই মুছে ফেলা যায় কিনা তা আপনি পরীক্ষা করতে পারেন! এই জাতীয় পরীক্ষাগুলি সঞ্চিত প্রক্রিয়া থেকে ত্রুটি বাড়াতে ভুলে যাওয়া এবং এই জাতীয় হাজার হাজার পরিস্থিতি যেমন প্রকাশিত করতে পারে ose
আমি মনে করি সত্তা কাঠামো আমি এতক্ষণ পড়া নিবন্ধগুলির চেয়ে ভাল সংগ্রহস্থল প্যাটার্ন প্রয়োগ করে এবং তারা অর্জন করার চেষ্টা করছে তার থেকে অনেক বেশি এগিয়ে যায়।
যে দিনগুলিতে আমরা এক্সবেস, অ্যাডক্স এবং অ্যাডো.নেট ব্যবহার করছিলাম সেগুলিতে রিপোজিটরিটি ছিল সেরা অনুশীলন, তবে সত্তার সাথে !! (সংগ্রহস্থল ওভার সংগ্রহস্থল)
শেষ অবধি আমার মনে হয় প্রচুর লোক সংগ্রহশৈলীর প্যাটার্ন শিখতে এবং প্রয়োগ করতে প্রচুর সময় ব্যয় করে এবং তারা তা যেতে অস্বীকার করে। বেশিরভাগ ক্ষেত্রে তারা তাদের সময় নষ্ট করেনি তা প্রমাণ করার জন্য।
এটি মাইগ্রেশনগুলির কারণে: মাইগ্রেশনগুলি কাজ করতে পারা সম্ভব নয়, কারণ সংযোগের স্ট্রিংটি ওয়েবকনফাইগে থাকে। কিন্তু, DbContext রিপোজিটরি স্তরটিতে থাকে। আইডিবি কনটেক্সটফ্যাক্টির ডাটাবেসে কনফিগারেশন স্ট্রিং থাকা দরকার B
চারপাশে কাজ আছে তবে আমি এর জন্য এখনও একটি পরিষ্কার সমাধান খুঁজে পাইনি!