আমি Gemini, আপনার Simple Coding Tutor। আজকের সেশনে আপনাকে স্বাগতম!

Outline অনুযায়ী আমরা এখন Section 24-এ আছি। আগের লেকচারে আমরা Clean Architecture-এর থিওরি (Overview) নিয়ে আলোচনা করেছিলাম। আজ আমরা প্র্যাকটিক্যালি Clean Architecture-এর সবচেয়ে গুরুত্বপূর্ণ অংশ—Core Layer (Lecture 326: Core) তৈরি করা শিখব। চলুন শুরু করা যাক!


📝 Lecture Summary

ভবিষ্যতে দ্রুত রিভিশন দেওয়ার জন্য পুরো লেকচারের মূল বিষয়গুলো নিচে দেওয়া হলো:

  • Core Layer Setup: Core layer হলো অ্যাপ্লিকেশনের প্রাণকেন্দ্র, যা UI এবং Database থেকে সম্পূর্ণ স্বাধীন।
  • Solution Organization: প্রজেক্টগুলোকে সুন্দরভাবে সাজানোর জন্য src এবং tests নামে Solution Folders তৈরি করা হয়েছে।
  • Project Creation: Core layer-এর জন্য একটি আলাদা Class Library প্রজেক্ট তৈরি করা হয়েছে।
  • Domain Layer Integration: Core প্রজেক্টের ভেতরে Domain ফোল্ডার তৈরি করে সেখানে Entities এবং RepositoryContracts রাখা হয়েছে।
  • Business Logic Migration: পুরনো প্রজেক্ট থেকে Exceptions, DTO, ServiceContracts, Services, Helpers, এবং Enums ফাইলগুলো Core প্রজেক্টে কপি করা হয়েছে।
  • NuGet Packages: Core প্রজেক্টে প্রয়োজনীয় প্যাকেজ (EPPlus, CsvHelper, DataAnnotations, Serilog) ইন্সটল করা হয়েছে।
  • Dependency Fix: Clean Architecture-এর রুল অনুযায়ী Core লেয়ার থেকে ডাটাবেস ডিপেন্ডেন্সি (Microsoft.EntityFrameworkCore namespace) ডিলিট করা হয়েছে।

🔍 Comprehensive Breakdown

The Core Layer - The Heart of the Project (Priority: 10/10)

Why: Core layer হলো আপনার অ্যাপ্লিকেশনের সেন্ট্রাল পার্ট। আপনার অ্যাপ্লিকেশনটি ASP.NET Core, Mobile App বা অন্য যেকোনো UI প্রযুক্তি ব্যবহার করুক না কেন, Business Logic সবসময় একই থাকে। Core layer কোনো নির্দিষ্ট Database (যেমন SQL Server বা Oracle) বা UI-এর ওপর নির্ভরশীল নয়। Database-এর কাজ Infrastructure layer সামলাবে।

Solution Structure Setup (Priority: 8/10)

Why: বড় প্রজেক্টে ফাইল এবং প্রজেক্টগুলো অর্গানাইজড রাখা খুব জরুরি।

  • লেকচারার প্রথমে একটি নতুন ASP.NET Core Web Project তৈরি করেছেন, যার নাম দিয়েছেন ContactsManager.UI
  • এরপর Solution-এ ডান ক্লিক করে দুটি Solution Folder তৈরি করেছেন: src (যেখানে মূল প্রজেক্টগুলো থাকবে) এবং tests (যেখানে টেস্টিং প্রজেক্টগুলো থাকবে)।
  • UI প্রজেক্টটিকে টেনে (drag and drop) src ফোল্ডারের ভেতরে নিয়ে যাওয়া হয়েছে।

Creating the Core Project (Priority: 10/10)

Why: Business Logic-কে আলাদা এবং স্বাধীন রাখার জন্য এটিকে একটি আলাদা প্রজেক্টে রাখতে হয়।

  • src ফোল্ডারের ওপর ডান ক্লিক করে একটি নতুন Class Library প্রজেক্ট তৈরি করা হয়েছে এবং নাম দেওয়া হয়েছে ContactsManager.Core
  • ডিফল্টভাবে তৈরি হওয়া Class1.cs ফাইলটি ডিলিট করে দেওয়া হয়েছে কারণ এর কোনো প্রয়োজন নেই।

Migrating Code to Core Layer (Priority: 10/10)

পুরনো প্রজেক্ট (Monolithic) থেকে ফাইলগুলো এনে Core লেয়ারে সুন্দরভাবে সাজানো হয়েছে:

  1. Domain Layer (Entities & RepositoryContracts): Core প্রজেক্টে একটি Domain ফোল্ডার তৈরি করা হয়েছে। Clean Architecture-এ Domain লেয়ার মূলত Core-এরই একটি অংশ। এর ভেতরে Entities (যেমন: Country.cs, Person.cs) এবং RepositoryContracts (যেমন: ICountriesRepository) কপি করা হয়েছে। (নোট: DbContext এখানে কপি করা হয়নি, কারণ এটি Infrastructure লেয়ারে যাবে)।
  2. Exceptions: Exceptions ফোল্ডার তৈরি করে কাস্টম এক্সেপশন ক্লাসগুলো রাখা হয়েছে।
  3. DTO (Data Transfer Objects): ক্লায়েন্ট এবং সার্ভারের মধ্যে ডাটা আদান-প্রদানের জন্য DTO ক্লাসগুলো রাখা হয়েছে।
  4. Service Contracts: Business Logic-এর Interface-গুলো (যেমন: ICountriesService) এখানে রাখা হয়েছে।
  5. Services: Interface-গুলোর Implementation (Business Logic) এখানে রাখা হয়েছে।
  6. Helpers & Enums: Reusable কোড (যেমন: Validation Helper, Password Hasher) এবং Enumeration-গুলো এই ফোল্ডারগুলোতে রাখা হয়েছে।

Installing NuGet Packages in Core (Priority: 7/10)

Core প্রজেক্ট নিজে স্বাধীন হলেও, Business Logic এক্সিকিউট করার জন্য এর কিছু থার্ড-পার্টি লাইব্রেরি প্রয়োজন হয়। লেকচারার নিচের প্যাকেজগুলো ইন্সটল করেছেন:

  • EPPlus & CsvHelper: Excel এবং CSV ফাইল জেনারেট করার জন্য।
  • Microsoft.AspNetCore.Mvc.DataAnnotations: DTO এবং Entity ক্লাসে Validation Rules (যেমন [Required]) অ্যাপ্লাই করার জন্য।
  • Serilog, Serilog.Timings, Serilog.Extensions.Hosting: Business Logic লেভেলে Logging করার জন্য।

Fixing Dependency Leaks (Priority: 10/10)

Why: Clean Architecture-এর প্রধান রুল হলো—Core লেয়ার কখনো Data Access লেয়ারের ওপর নির্ভর করবে না। পুরনো প্রজেক্টের Service ক্লাসগুলোতে Microsoft.EntityFrameworkCore namespace-টি import করা ছিল। লেকচারার সবগুলো Service ফাইল ওপেন করে এই namespace-টি ডিলিট করে দিয়েছেন। কারণ Entity Framework Core হলো Database-এর প্রযুক্তি, যা Infrastructure লেয়ারের অংশ। Core লেয়ারে এর কোনো অস্তিত্ব থাকা উচিত নয়।


💻 Code Implementation & .NET 10 Updates

Clean Architecture Folder Structure (Core Project): আপনার ContactsManager.Core প্রজেক্টের স্ট্রাকচার দেখতে অনেকটা এমন হবে:

ContactsManager.Core (Class Library)
 ┣ 📂 Domain
 ┃ ┣ 📂 Entities (e.g., Person.cs)
 ┃ ┗ 📂 RepositoryContracts (e.g., IPersonsRepository.cs)
 ┣ 📂 DTO (e.g., PersonAddRequest.cs)
 ┣ 📂 Exceptions
 ┣ 📂 Helpers
 ┣ 📂 Enums
 ┣ 📂 ServiceContracts (e.g., IPersonsService.cs)
 ┗ 📂 Services (e.g., PersonsService.cs)
 

.NET 10 Update (Primary Constructors in Services): লেকচারে দেখানো Service ক্লাসগুলো যদি পুরনো ভার্সনের হয়, তবে .NET 10 (এবং C# 12+) এ আপনি Primary Constructors ব্যবহার করে কোড আরও ক্লিন করতে পারেন।

Old Way (C# 9/10):

public class PersonsService : IPersonsService
{
    private readonly IPersonsRepository _personsRepository;
 
    public PersonsService(IPersonsRepository personsRepository)
    {
        _personsRepository = personsRepository;
    }
    // ... methods ...
}
 

.NET 10 Way (Using Primary Constructors):

// Constructor সরাসরি ক্লাসের নামের পাশেই ডিক্লেয়ার করা যায়
public class PersonsService(IPersonsRepository personsRepository) : IPersonsService
{
    // এখন আপনি সরাসরি personsRepository ভেরিয়েবলটি মেথডের ভেতর ব্যবহার করতে পারবেন
    public async Task<PersonResponse> AddPerson(PersonAddRequest? request)
    {
        // Business logic here...
    }
}
 

🌟 Best Practices

  • No Framework Dependencies in Core: Core প্রজেক্টে কখনোই Microsoft.EntityFrameworkCore বা Microsoft.Data.SqlClient জাতীয় কোনো প্যাকেজ ইন্সটল করবেন না। Core-কে সম্পূর্ণ Database-agnostic রাখুন।
  • Use DTOs for Output: Service থেকে কখনোই সরাসরি Entity Class (যেমন Person) রিটার্ন করবেন না। সবসময় PersonResponse বা এর মতো DTO ব্যবহার করবেন। এটি ডাটাবেসের স্ট্রাকচারকে বাইরের দুনিয়া থেকে হাইড করে রাখে।
  • Organize by Feature (Optional): প্রজেক্ট অনেক বড় হয়ে গেলে Services এবং DTO ফোল্ডারের বদলে ফোল্ডার স্ট্রাকচারকে ফিচার অনুযায়ী সাজানো ভালো (যেমন: 📂 Persons -> PersonsService.cs, PersonDTO.cs)।