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

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


📝 Lecture Summary

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

  • UI Project Cleanup: ভুল প্রজেক্ট টেমপ্লেটের কারণে তৈরি হওয়া ডিফল্ট Pages ফোল্ডার এবং wwwroot-এর অপ্রয়োজনীয় CSS/JS ফাইল ডিলিট করা হয়েছে।
  • Code Migration: পুরনো প্রজেক্ট থেকে ASP.NET Core স্পেসিফিক ফাইলগুলো (Controllers, Views, Middleware, Filters, appsettings.json, Program.cs) UI প্রজেক্টে কপি করা হয়েছে।
  • Project References: UI প্রজেক্ট থেকে Core প্রজেক্টের রেফারেন্স অ্যাড করা হয়েছে। এছাড়া Dependency Injection (DI) কনফিগার করার জন্য Infrastructure প্রজেক্টেরও রেফারেন্স অ্যাড করা হয়েছে।
  • NuGet Packages: UI প্রজেক্টে Entity Framework Core, EF Core Tools, Rotativa এবং Serilog-এর প্যাকেজগুলো ইন্সটল করা হয়েছে।
  • Database Migrations: Package Manager Console (PMC)-এ Infrastructure প্রজেক্ট সিলেক্ট করে Add-Migration এবং Update-Database কমান্ড চালিয়ে ডাটাবেস তৈরি করা হয়েছে।

🔍 Comprehensive Breakdown

1. UI Project Cleanup & Migration (Priority: 8/10)

Why: প্রজেক্ট তৈরির সময় “Empty” টেমপ্লেটের বদলে “Web Application” সিলেক্ট করায় কিছু অপ্রয়োজনীয় ডেমো ফাইল তৈরি হয়েছিল। আমাদের নিজস্ব Custom CSS এবং Views থাকায় ওই ডিফল্ট ফাইলগুলোর কোনো দরকার নেই।

  • Action: UI প্রজেক্টের wwwroot ফোল্ডার থেকে favicon.ico বাদে বাকি সব ডিলিট করা হয়েছে। এছাড়া পুরো Pages ফোল্ডার ডিলিট করা হয়েছে।
  • Migration: পুরনো মনোলিথিক প্রজেক্ট থেকে Controllers, Filters, Middleware, StartupExtensions, Views, wwwroot (custom files), appsettings.json, appsettings.Development.json, ডাটা ফাইলগুলো এবং Program.cs কপি করে নতুন UI প্রজেক্টে পেস্ট ও Overwrite করা হয়েছে।

2. Configuring Project References (Priority: 10/10)

Why: Clean Architecture-এর মূল নিয়ম হলো UI লেয়ার Core লেয়ারের ওপর নির্ভর করবে। কিন্তু লেকচারার এখানে একটি বিশেষ কাজ করেছেন—তিনি UI লেয়ারে Infrastructure লেয়ারেরও রেফারেন্স অ্যাড করেছেন। কেন? কারণ, Program.cs ফাইলে আমাদের IoC Container-এ (Dependency Injection) সার্ভিসগুলো রেজিস্টার করতে হয়। Infrastructure লেয়ারে থাকা ApplicationDbContext এবং Repository ক্লাসগুলোকে Program.cs-এ রেজিস্টার করার জন্যই এই রেফারেন্সটি সাময়িকভাবে প্রয়োজন হয়।

  • Action: UI প্রজেক্টের Dependencies-এ রাইট ক্লিক করে Add Project Reference থেকে Core এবং Infrastructure দুটোকেই সিলেক্ট করা হয়েছে।
  • (Visual Studio Code Shortcut): টার্মিনালে নিচের কমান্ড দুটি ব্যবহার করুন:
dotnet add ContactsManager.UI/ContactsManager.UI.csproj reference ContactsManager.Core/ContactsManager.Core.csproj
dotnet add ContactsManager.UI/ContactsManager.UI.csproj reference ContactsManager.Infrastructure/ContactsManager.Infrastructure.csproj
 

3. Installing NuGet Packages (Priority: 9/10)

Why: UI লেয়ারই যেহেতু আমাদের অ্যাপ্লিকেশনের Entry Point, তাই থার্ড-পার্টি লাইব্রেরিগুলো ইনিশিয়ালাইজ করার জন্য প্যাকেজগুলো এখানেও ইন্সটল করতে হয়।

  • Entity Framework: Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.SqlServer (DI সেটাপের জন্য) এবং Microsoft.EntityFrameworkCore.Tools (Migration কমান্ড চালানোর জন্য)।
  • Rotativa: Rotativa.AspNetCore (PDF জেনারেট করার জন্য)।
  • Serilog: Serilog, Serilog.AspNetCore, Serilog.Sinks.MSSqlServer, Serilog.Sinks.Seq (লগিং কনফিগারেশনের জন্য)।

4. Code-First Migrations & Database Creation (Priority: 10/10)

Why: আমাদের নতুন স্ট্রাকচারে Database তৈরি করতে হবে।

  • Connection String: প্রথমে appsettings.json ফাইলে ডাটাবেসের নাম আপডেট করে contacts-database দেওয়া হয়েছে।
  • Migrations Target: এটি খুবই গুরুত্বপূর্ণ! Package Manager Console (PMC) ওপেন করে Default project ড্রপডাউন থেকে ContactsManager.Infrastructure সিলেক্ট করতে হবে। কারণ আমাদের ApplicationDbContext ফাইলটি Infrastructure প্রজেক্টে আছে।
  • Commands:
  1. Add-Migration Initial (এটি Migration ফাইল তৈরি করবে)
  2. Update-Database (এটি SQL Server-এ ডাটাবেস এবং টেবিল তৈরি করবে)
  • (Visual Studio Code / CLI Shortcut): CLI ব্যবহার করলে প্রজেক্ট ফ্ল্যাগ (--project) দিয়ে Infrastructure প্রজেক্ট দেখিয়ে দিতে হবে:
dotnet ef migrations add Initial --project ContactsManager.Infrastructure --startup-project ContactsManager.UI
dotnet ef database update --project ContactsManager.Infrastructure --startup-project ContactsManager.UI
 

💻 Code Implementation (Dependency Injection in UI)

যে কারণে আমাদের UI প্রজেক্টে Infrastructure-এর রেফারেন্স নিতে হলো, তার একটি উদাহরণ Program.cs-এ দেখা যাক:

using ContactsManager.Core.Domain.RepositoryContracts;
using ContactsManager.Infrastructure.DbContext;
using ContactsManager.Infrastructure.Repositories;
using Microsoft.EntityFrameworkCore;
 
var builder = WebApplication.CreateBuilder(args);
 
// UI প্রজেক্ট থেকে Infrastructure-এর DbContext রেজিস্টার করা হচ্ছে
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
 
// UI প্রজেক্ট থেকে Infrastructure-এর Repository রেজিস্টার করা হচ্ছে
builder.Services.AddScoped<IPersonsRepository, PersonsRepository>();
 
var app = builder.Build();
// ... remaining middleware code
 

🌟 Best Practices & .NET 10 Updates

  • Keep Controllers Thin (Best Practice): Clean Architecture-এ Controller-এর কাজ হলো শুধুমাত্র HTTP Request রিসিভ করা এবং Response রিটার্ন করা। কোনো Business Logic বা Database কুয়েরি সরাসরি Controller-এ লিখবেন না। Controller শুধু Core লেয়ারের Service-কে কল করবে।
  • Migration Assembly (Best Practice): UI প্রজেক্ট থেকে Infrastructure-এর রেফারেন্স সরানোর জন্য বড় প্রজেক্টগুলোতে DI-এর কাজ Infrastructure লেয়ারেই একটি Extension Method-এর মাধ্যমে করা হয় এবং Program.cs-এ শুধু সেই মেথডটি কল করা হয়। এতে UI প্রজেক্ট Infrastructure সম্পর্কে কিছুই জানতে পারে না।

.NET 10 Update (Clean Program.cs): .NET 10-এ Program.cs ফাইল অনেক বেশি মডুলার। আপনি চাইলে Dependency Injection-এর কোডগুলো আলাদা ফাইলে (যেমন DependencyInjection.cs) রাখতে পারেন।

// UI প্রজেক্টের Extension Method (.NET 10 Style)
public static class DependencyInjection
{
    public static IServiceCollection AddInfrastructureServices(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
            
        services.AddScoped<IPersonsRepository, PersonsRepository>();
        return services;
    }
}
 
// Program.cs-এ শুধু কল করুন:
builder.Services.AddInfrastructureServices(builder.Configuration);