হ্যালো হাসিব! তুমি এখন Section 12: Dependency Injection-এর একদম শেষ লেকচার “Autofac” (Lecture 140)-এ আছো।

এতক্ষণ আমরা ASP.NET Core-এর ডিফল্ট বা বিল্ট-ইন IoC Container (builder.Services) ব্যবহার করে আসছিলাম। কিন্তু প্রফেশনাল এবং অনেক বড় প্রোজেক্টে কিছু অ্যাডভান্সড ফিচারের জন্য ডেভেলপাররা থার্ড-পার্টি IoC Container ব্যবহার করে। এর মধ্যে সবচেয়ে পপুলার হলো Autofac

আজকের লেকচারে আমরা শিখবো কেন Autofac দরকার এবং কীভাবে ডিফল্ট DI Container-কে রিপ্লেস করে Autofac সেটআপ করতে হয়।

চলো, লেকচারটি ডিকোড করি।


সারসংক্ষেপ (Quick Revision List)

  • Autofac কী: এটি ASP.NET Core-এর বিল্ট-ইন IoC Container-এর একটি থার্ড-পার্টি (Third-party) বিকল্প।

  • কেন ব্যবহার করবো: বিল্ট-ইন Container-এ শুধু ৩টি Lifetime আছে। কিন্তু Autofac-এ আরও ২টি অ্যাডভান্সড Lifetime (InstancePerOwned, InstancePerMatchingLifetimeScope) এবং কিছু এক্সট্রা ফিচার (যেমন: Metadata, Decorators) আছে।

  • Set up in 3 Steps: ১. NuGet Package Manager থেকে Autofac এবং Autofac.Extensions.DependencyInjection প্যাকেজ ইনস্টল করা। ২. Program.csbuilder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) লিখে ডিফল্ট Container-কে রিপ্লেস করা। ৩. builder.Host.ConfigureContainer<ContainerBuilder>(...) এর মাধ্যমে সার্ভিস রেজিস্টার করা।

  • Service Registration in Autofac:

  • builder.RegisterType<Class>().As<Interface>().InstancePerDependency() (Transient-এর সমতুল্য)

  • builder.RegisterType<Class>().As<Interface>().InstancePerLifetimeScope() (Scoped-এর সমতুল্য)

  • builder.RegisterType<Class>().As<Interface>().SingleInstance() (Singleton-এর সমতুল্য)

  • Child Scope in Autofac: IServiceScopeFactory-এর বদলে ILifetimeScope ইনজেক্ট করে BeginLifetimeScope() কল করতে হয় এবং GetRequiredService-এর বদলে Resolve<T>() ব্যবহার করতে হয়।


Comprehensive Breakdown

১. Autofac-এর প্রয়োজনীয়তা (Why Autofac?) [Priority: 7/10]

ASP.NET Core-এর বিল্ট-ইন DI Container খুবই পাওয়ারফুল, কিন্তু এর কিছু লিমিটেশন আছে।

  • এতে শুধু ৩টি Lifetime আছে (Transient, Scoped, Singleton)।
  • বড় এন্টারপ্রাইজ প্রোজেক্টে যদি কোনো সার্ভিসকে ক্লাসগুলোর রিলেশনশিপ অনুযায়ী (Relationship-based) বা নামের ম্যাচিং অনুযায়ী (Name-matching) ইনস্ট্যান্সিয়েট (Instantiate) করতে হয়, তবে বিল্ট-ইন DI তা পারে না।
  • Autofac এই গ্যাপ পূরণ করে এবং Decorators (সার্ভিসের উপর র‍্যাপার) বা Metadata এর মতো অ্যাডভান্সড ফিচার দেয়।

২. Autofac ইনস্টল করা (NuGet Package) [Priority: 10/10]

Autofac ব্যবহার করার জন্য প্রোজেক্টে এর লাইব্রেরি অ্যাড করতে হবে।

  1. Web Project-এর Dependencies-এ রাইট-ক্লিক করে Manage NuGet Packages-এ যাও।
  2. Search ট্যাবে গিয়ে সার্চ করো:
  • Autofac
  • Autofac.Extensions.DependencyInjection
  1. এই দুটি প্যাকেজ (লেকচারারের ব্যবহৃত ভার্সন অনুযায়ী) ইনস্টল করো।

VS Code CLI Shortcut: টার্মিনালে গিয়ে নিচের কমান্ডগুলো রান করলে প্যাকেজ ইনস্টল হয়ে যাবে:

dotnet add package Autofac
dotnet add package Autofac.Extensions.DependencyInjection
 

৩. Program.cs-এ Autofac কনফিগার করা [Priority: 10/10]

এখন ডিফল্ট Container-কে সরিয়ে Autofac-কে বসাতে হবে এবং সার্ভিস রেজিস্টার করতে হবে।

Code Implementation (Program.cs):

using Autofac;
using Autofac.Extensions.DependencyInjection;
// (অন্যান্য প্রয়োজনীয় Namespace)
 
var builder = WebApplication.CreateBuilder(args);
 
// ১. Default DI Container-কে Autofac দিয়ে Replace করা হচ্ছে
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
 
// ২. Autofac Container-এ Service Register করা হচ্ছে
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    // Transient-এর সমতুল্য:
    // containerBuilder.RegisterType<CitiesService>().As<ICitiesService>().InstancePerDependency();
 
    // Singleton-এর সমতুল্য:
    // containerBuilder.RegisterType<CitiesService>().As<ICitiesService>().SingleInstance();
 
    // Scoped-এর সমতুল্য (আমরা এটাই ব্যবহার করছি):
    containerBuilder.RegisterType<CitiesService>().As<ICitiesService>().InstancePerLifetimeScope();
});
 
builder.Services.AddControllersWithViews();
// ... (বাকি কনফিগারেশন আগের মতোই)
 

৪. Child Scope-এর কোড আপডেট করা (HomeController) [Priority: 8/10]

আগের লেকচারে আমরা ম্যানুয়ালি Child Scope বানানোর জন্য IServiceScopeFactory ব্যবহার করেছিলাম। কিন্তু যেহেতু এখন আমরা Autofac ব্যবহার করছি, তাই Autofac-এর নিজস্ব ইন্টারফেস ব্যবহার করতে হবে।

  • IServiceScopeFactory-এর বদলে ILifetimeScope ইনজেক্ট করতে হবে।
  • CreateScope()-এর বদলে BeginLifetimeScope() কল করতে হবে।
  • GetRequiredService<T>()-এর বদলে Resolve<T>() কল করতে হবে।

Code Implementation (Controllers/HomeController.cs):

using Autofac; // Autofac Namespace ইমপোর্ট করতে হবে
using Microsoft.AspNetCore.Mvc;
 
public class HomeController : Controller
{
    private readonly ICitiesService _citiesService;
    private readonly ILifetimeScope _lifetimeScope; // Autofac interface
 
    public HomeController(ICitiesService citiesService, ILifetimeScope lifetimeScope)
    {
        _citiesService = citiesService;
        _lifetimeScope = lifetimeScope;
    }
 
    [Route("/")]
    public IActionResult Index()
    {
        // Child Scope তৈরি করা
        using (var scope = _lifetimeScope.BeginLifetimeScope())
        {
            // Autofac-এর Resolve মেথড দিয়ে সার্ভিস রিসিভ করা
            ICitiesService childScopedService = scope.Resolve<ICitiesService>();
            ViewBag.InstanceId_InChildScope = childScopedService.ServiceInstanceId;
        }
 
        return View(_citiesService.GetCities());
    }
}
 

(এই চেঞ্জগুলো বাদে আউটপুট এবং লজিক আগের মতোই কাজ করবে)।


VS / VS Code Shortcuts

  • Manage NuGet Packages (VS Code): VS Code-এ NuGet Package ম্যানেজ করার জন্য NuGet Gallery নামের এক্সটেনশনটি খুবই জনপ্রিয়। Ctrl + Shift + P চেপে “NuGet: Open NuGet Gallery” সার্চ করে অনায়াসেই প্যাকেজ ইনস্টল করা যায়।

Best Practices & .NET 10 Context

Best Practices for Autofac:

  1. When to use: যদি তোমার প্রোজেক্ট ছোট বা মাঝারি হয়, তবে ভুলেও Autofac ব্যবহার করবে না। ASP.NET Core-এর বিল্ট-ইন DI যথেষ্ট পাওয়ারফুল এবং ফাস্ট। Autofac শুধুমাত্র তখন ব্যবহার করবে যখন তোমার প্রোজেক্টে খুব কমপ্লেক্স আর্কিটেকচার (যেমন: Domain-Driven Design, Multiple interceptors) বা থার্ড-পার্টি প্লাগইন আর্কিটেকচার দরকার।
  2. Module Registration: Autofac-এর সবচেয়ে বড় সুবিধা হলো এর Module সিস্টেম। তুমি চাইলে বিভিন্ন লেয়ারের (যেমন Database layer, API layer) সার্ভিসগুলোকে আলাদা আলাদা Module ক্লাসে গ্রুপ করে রাখতে পারো, যা কোডকে অনেক ক্লিন করে।

.NET 10 Context: ASP.NET Core 10-এও বিল্ট-ইন DI Container-এর ক্ষমতা আগের চেয়ে অনেক বেড়েছে (যেমন: Keyed Services)। তাই .NET 10-এ Autofac-এর ব্যবহার আগের চেয়ে কিছুটা কমেছে। তবে Autofac এখনো .NET 10 পুরোপুরি সাপোর্ট করে এবং কনফিগারেশনের সিনট্যাক্স এই লেকচারের মতোই হুবহু এক।

Keyed Services in .NET 10 (Autofac-এর বিকল্প): Autofac-এর InstancePerMatchingLifetimeScope বা নাম ধরে সার্ভিস খোঁজার যে সুবিধাটি ছিল, .NET 8/10-এ তা Keyed Services নামে বিল্ট-ইন অ্যাড হয়ে গেছে!

// .NET 10 Built-in DI (No Autofac needed for this!)
builder.Services.AddKeyedScoped<ICitiesService, CitiesService>("databaseService");
builder.Services.AddKeyedScoped<ICitiesService, MockCitiesService>("mockService");
 
// In Controller:
public HomeController([FromKeyedServices("databaseService")] ICitiesService service) { ... }
 

হাসিব, এই লেকচারের মাধ্যমে আমাদের কোর্সের সবচেয়ে ক্রিটিক্যাল সেকশন “Dependency Injection” সফলভাবে শেষ হলো! Autofac এবং DI-এর পুরো জার্নিটা কি তোমার কাছে ক্লিয়ার হয়েছে? তুমি রেডি থাকলে আমরা নেক্সট সেকশন “Environments” শুরু করতে পারি!