হ্যালো হাসিব! আমরা আগের লেকচারে UI সেটআপ করেছিলাম, আর এই লেকচারটি হচ্ছে সেই UI-তে দেখানোর জন্য “Mock Data” বা ডামি ডাটা তৈরি করা নিয়ে। যেহেতু ডাটাবেস ইমপ্লিমেন্টেশন এখনো হয়নি, তাই অ্যাপ্লিকেশন রান করলে গ্রিড যেন ফাঁকা না থাকে, সেজন্য আমরা সার্ভিসের ভেতরেই কিছু ডাটা হার্ডকোড করে দিচ্ছি।
চলো লেকচারটির বিস্তারিত ব্রেকডাউন দেখে নিই।
📌 Quick Summary for Revision
initializeFlag:CountriesServiceএবংPersonsService-এর Constructor-এbool initialize = trueপ্যারামিটার অ্যাড করা হয়েছে।- Unit Test Update: Unit Test প্রজেক্টে সার্ভিসগুলোর অবজেক্ট তৈরির সময়
initialize: falseপাস করা হয়েছে, যেন টেস্ট করার সময় লিস্ট একদম ফাঁকা থাকে। - GUID Generation: Visual Studio-এর “Create GUID” টুল ব্যবহার করে ইউনিক Country ID এবং Person ID তৈরি করা হয়েছে।
- Mockaroo Website: রিয়েলিস্টিক ডামি ডাটা (নাম, ইমেইল, বয়স ইত্যাদি) জেনারেট করার জন্য mockaroo.com ব্যবহার করা হয়েছে।
- Foreign Key Mapping: Person অবজেক্টের
CountryIDফিল্ডেCountriesService-এর জেনারেট করা Country ID গুলো ম্যানুয়ালি বসিয়ে রিলেশন তৈরি করা হয়েছে।
🚀 Comprehensive Breakdown & The “Why”
১. Service Constructor-এ initialize Flag যুক্ত করা [Priority: 10/10]
The “Why”: আমরা চাই যখন প্রজেক্ট রান করবে, তখন Dependency Injection (DI) যেন সার্ভিসের সাথে কিছু ডামি ডাটা তৈরি করে দেয়। কিন্তু Unit Testing-এর সময় আমাদের শর্ত ছিল “লিস্ট বাই ডিফল্ট ফাঁকা থাকতে হবে”। এখন যদি Constructor-এ ডাটা হার্ডকোড করা থাকে, তাহলে টেস্টগুলো ফেইল করবে। এই সমস্যা সমাধানের জন্যই initialize নামের একটি অপশনাল প্যারামিটার নেওয়া হয়েছে। DI ডিফল্টভাবে true পাস করবে, আর টেস্টের সময় আমরা ম্যানুয়ালি false পাস করবো।
Implementation:
public class CountriesService : ICountriesService
{
private readonly List<CountryResponse> _countries;
// Default parameter initialize = true
public CountriesService(bool initialize = true)
{
_countries = new List<CountryResponse>();
if (initialize)
{
// Add Mock Data here
_countries.AddRange(new List<CountryResponse> {
new CountryResponse { CountryID = Guid.Parse("E4B651B6-7B8B-4B3B-8C93-47027CEFBEB3"), CountryName = "USA" },
new CountryResponse { CountryID = Guid.Parse("C7249E69-952F-433E-BE6C-32B5EB6A985D"), CountryName = "India" }
});
}
}
}
২. Unit Tests আপডেট করা [Priority: 9/10]
The “Why”: যেহেতু সার্ভিসের Constructor আপডেট হয়েছে, তাই CountriesServiceTest এবং PersonsServiceTest ক্লাসগুলোতে গিয়ে Constructor কলের জায়গায় false পাস করতে হবে। নাহলে আগের লেখা টেস্টগুলো ফেইল করবে।
Implementation:
// Inside PersonsServiceTest or CountriesServiceTest Constructor
_countriesService = new CountriesService(false); // initialize = false
_personsService = new PersonsService(false);
৩. GUID জেনারেট করা [Priority: 5/10]
The “Why”: ডাটাবেসে প্রতিটি Country এবং Person-এর একটি Unique Primary Key (ID) থাকতে হয়। এখানে GUID (Globally Unique Identifier) ব্যবহার করা হচ্ছে।
- Visual Studio Method:
Tools->Create GUID->Registry Formatসিলেক্ট করে নতুন GUID জেনারেট করে কপি করা হয়েছে এবং কার্লি ব্র্যাকেট{}রিমুভ করে কোডে বসানো হয়েছে।
৪. Mockaroo দিয়ে Dummy Data জেনারেট করা [Priority: 6/10]
The “Why”: ম্যানুয়ালি ১০-২০ জন মানুষের নাম, ইমেইল, ঠিকানা চিন্তা করে লেখা অনেক সময়সাপেক্ষ ব্যাপার। Mockaroo একটি দারুণ থার্ড-পার্টি ওয়েবসাইট, যেখানে আপনি ফিল্ডের নাম এবং টাইপ (First Name, Email, Date, Boolean) বলে দিলে সে রিয়েলিস্টিক ডাটা জেনারেট করে দেয়।
- লেকচারে CSV ফরম্যাট সিলেক্ট করে ১০টি রো জেনারেট করে সেগুলোকে কপি করে কোডে কমেন্ট হিসেবে রাখা হয়েছে এবং পরে Person অবজেক্টে বসানো হয়েছে।
- Important: প্রতিটি Person-এর
CountryIDএর জায়গায় অবশ্যইCountriesServiceএ যে GUID গুলো ব্যবহার করা হয়েছে, সেগুলো বসাতে হবে, নাহলে Foreign Key রিলেশন কাজ করবে না।
Implementation:
_persons.Add(new PersonResponse
{
PersonID = Guid.Parse("..."),
PersonName = "John Doe",
Email = "john@example.com",
DateOfBirth = DateTime.Parse("1995-01-01"),
Gender = "Male",
Address = "123 Main St",
ReceiveNewsLetters = true,
CountryID = Guid.Parse("E4B651B6-7B8B-4B3B-8C93-47027CEFBEB3") // Matching USA's ID
});
🆕 .NET 10 & Modern Approaches
লেকচারে Service ক্লাসের ভেতরে যেভাবে initialize প্যারামিটার দিয়ে হার্ডকোড করে ডাটা রাখা হয়েছে, এটি মূলত লার্নিং পারপাসে করা। .NET 10 (বা আধুনিক যেকোনো ভার্সনে) এর জন্য আরো স্মার্ট কিছু অ্যাপ্রোচ আছে:
- Collection Expressions (C# 12/13):
new List<CountryResponse> { ... }লেখার বদলে এখন সরাসরি[...]ব্যবহার করা যায়, যা কোড অনেক ক্লিন রাখে।
_countries.AddRange(
[
new CountryResponse { CountryID = Guid.NewGuid(), CountryName = "USA" },
new CountryResponse { CountryID = Guid.NewGuid(), CountryName = "India" }
]);
- Bogus Library for Mock Data: Mockaroo থেকে কপি-পেস্ট না করে .NET-এ Bogus নামের একটি জনপ্রিয় লাইব্রেরি আছে। এটি দিয়ে কোডের মাধ্যমেই হাজার হাজার রিয়েলিস্টিক ডামি ডাটা জেনারেট করা যায়।
// Using Bogus package
var fakePersons = new Faker<Person>()
.RuleFor(p => p.PersonName, f => f.Name.FullName())
.RuleFor(p => p.Email, f => f.Internet.Email())
.RuleFor(p => p.PersonID, f => Guid.NewGuid());
⌨️ IDE Shortcuts
- Generate GUID: * Visual Studio:
Tools -> Create GUIDমেনু ছাড়াও, কোডের ভেতরেGuid.NewGuid().ToString()লিখে একবার রান করে কনসোল থেকে কপি করে নেওয়া যায়। - Visual Studio Code: “Insert GUID” নামের একটি এক্সটেনশন ইনস্টল করে নিলে
F1চেপেInsert GUIDকমান্ড দিলেই কোডে সরাসরি GUID বসে যায়।
💡 Best Practices
১. Never hardcode in Services: রিয়েল-ওয়ার্ল্ড প্রজেক্টে কখনোই Business Logic (Service Layer) এর ভেতরে ডামি ডাটা হার্ডকোড করা উচিত নয়। এর বদলে Entity Framework-এর Data Seeding ফিচার (যা DbContext এর OnModelCreating মেথডে থাকে) ব্যবহার করা বেস্ট প্র্যাকটিস।
২. JSON Configuration for Mock Data: যদি ডাটাবেস ছাড়া Mock Data ব্যবহার করতেই হয়, তবে ডাটাগুলো একটি mockdata.json ফাইলে রেখে অ্যাপ্লিকেশনের স্টার্টআপে ফাইলটি রিড করে অবজেক্টে কনভার্ট করা অনেক বেশি ক্লিন এবং মেইনটেইনেবল অ্যাপ্রোচ।
এই ডাটাগুলোর সাহায্যে পরের লেকচারেই আমরা Persons-এর Index ভিউ (গ্রিড) রেন্ডার করবো। কোনো কনফিউশন থাকলে জানাতে পারো!