চমৎকার! আজকের লেকচারটি ছোট হলেও প্রফেশনাল কোডবেস মেইনটেইন করার জন্য খুবই গুরুত্বপূর্ণ। এতোদিন আমরা দেখেছি প্রতিটি Controller-এর ওপরে একই Attribute বারবার লিখতে হয়। আজ আমরা শিখবো কীভাবে একটি Custom Base Class তৈরি করে এই পুনরাবৃত্তি (repetition) কমানো যায় এবং কোডকে আরও ক্লিন রাখা যায়।
চলুন শুরু করা যাক!
📝 Lecture Summary
ভবিষ্যতে দ্রুত রিভিশন দেওয়ার জন্য পুরো লেকচারের মূল বিষয়গুলো নিচে তালিকাভুক্ত করা হলো:
- The Problem: প্রতিটি Web API Controller-এ
[ApiController],[Route]এবংControllerBaseইনহেরিট করা বাধ্যতামূলক, যা বারবার লিখতে হয়। - The Solution: একটি
CustomControllerBaseক্লাস তৈরি করা, যা নিজেControllerBaseথেকে ইনহেরিট করবে এবং এর ওপরে প্রয়োজনীয় Attribute গুলো থাকবে। - Inheritance Rule: Object-Oriented Programming-এর নিয়ম অনুযায়ী, Parent Class-এর ওপর থাকা Attribute গুলো স্বয়ংক্রিয়ভাবে Child Class-এ অ্যাপ্লাই হয়ে যায়।
- Code Reusability: এই Base Class-এ আমরা চাইলে বিভিন্ন কমন
protectedমেথড রাখতে পারি, যা সব Controller থেকে সহজেই অ্যাক্সেস করা যাবে। - No Functional Change: এই পরিবর্তনের ফলে API-এর আউটপুট বা পারফরম্যান্সে কোনো পরিবর্তন আসে না, শুধু কোডের আর্কিটেকচার সুন্দর হয়।
🧠 Comprehensive Breakdown
নিচে লেকচারের প্রতিটি কনসেপ্ট বিস্তারিত এবং সহজভাবে ব্যাখ্যা করা হলো।
১. The Repetition Problem (Importance: 8/10)
Web API তৈরি করার সময় আমরা দেখেছি যে, CitiesController হোক বা TestController—সবখানেই আমাদের ControllerBase ক্লাস ইনহেরিট করতে হয় এবং [ApiController] ও [Route("api/[controller]")] অ্যাট্রিবিউট দুটি লিখতে হয়।
Why fix this? প্রজেক্ট যখন বড় হয় এবং আপনার ২০-৩০টি Controller থাকে, তখন একই কোড বারবার লেখা DRY (Don’t Repeat Yourself) প্রিন্সিপালের পরিপন্থী। এতে কোড দেখতেও নোংরা লাগে।
২. Creating a Custom Base Class (Importance: 10/10)
এই সমস্যা সমাধানের জন্য আমরা একটি নতুন ক্লাস তৈরি করবো, যার নাম দেওয়া হয়েছে CustomControllerBase (আপনি চাইলে যেকোনো নাম দিতে পারেন, যেমন: BaseApiController)।
The Hierarchy (পারিবারিক কাঠামো):
- Grandparent:
ControllerBase(ASP.NET Core এর বিল্ট-ইন ক্লাস) - Parent:
CustomControllerBase(আমাদের তৈরি করা ক্লাস, যা Grandparent থেকে ইনহেরিট করবে) - Child:
CitiesController,TestControllerইত্যাদি (যারা Parent থেকে ইনহেরিট করবে)
যেহেতু Parent ক্লাসের ওপরে [ApiController] এবং [Route] দেওয়া থাকবে, তাই চাইল্ড ক্লাসগুলোর ওপরে আর নতুন করে এগুলো লেখার দরকার নেই। ফ্রেমওয়ার্ক স্বয়ংক্রিয়ভাবে বুঝে নেবে যে চাইল্ড ক্লাসগুলোও এই রুলস ফলো করছে।
💡 VS Code Shortcut for Generating Class: ভিডিওতে দেখানো হয়েছে Visual Studio-তে নামের ওপর Right Click করে “Quick Actions > Generate class in a new file” সিলেক্ট করতে। আপনি যদি Visual Studio Code ব্যবহার করেন, তবে যে ক্লাসের নামটি আপনি মাত্র লিখেছেন (যা এখনো ফিজিক্যালি তৈরি হয়নি), সেটির ওপর মাউসের কার্সর রেখে কীবোর্ডে
Ctrl + .(Mac-এCmd + .) চাপুন। একটি মেনু আসবে, সেখান থেকে “Generate class ‘CustomControllerBase’ in new file” সিলেক্ট করলে অটোমেটিক ফাইল তৈরি হয়ে যাবে।
৩. Adding Common Methods (Importance: 7/10)
Base Class তৈরি করার আরেকটি বড় সুবিধা হলো Reusability। ধরুন, আপনার এমন একটি লজিক দরকার যা প্রায় সব Controller-এই কাজে লাগে (যেমন: বর্তমান লগ-ইন করা ইউজারের ID বের করা)। আপনি যদি সেই লজিকটি একটি protected মেথড হিসেবে CustomControllerBase এর ভেতর লিখে রাখেন, তবে আপনার প্রজেক্টের যেকোনো Controller থেকে সেটি সরাসরি কল করা যাবে।
💻 Code Implementation (.NET 10 Structure)
নিচে সম্পূর্ণ আর্কিটেকচারটি কীভাবে কাজ করে তা কোডের মাধ্যমে দেখানো হলো:
১. The Parent Class (CustomControllerBase.cs):
using Microsoft.AspNetCore.Mvc;
namespace CitiesManager.WebApi.Controllers
{
// ১. কমন রাউটিং এখানে দেওয়া হলো
[Route("api/[controller]")]
// ২. এপিআই কন্ট্রোলার অ্যাট্রিবিউট এখানে দেওয়া হলো
[ApiController]
// Best Practice: Base class সবসময় abstract রাখা উচিত, যাতে কেউ এর সরাসরি Object বানাতে না পারে।
public abstract class CustomControllerBase : ControllerBase
{
// উদাহরণ: একটি কমন মেথড যা সব Controller ব্যবহার করতে পারবে
protected string GetSuccessMessage(string actionName)
{
return $"Successfully completed the {actionName} operation.";
}
}
}
২. The Child Class (CitiesController.cs):
এখন আমাদের মেইন Controller গুলো দেখতে একদম ক্লিন হয়ে যাবে!
using Microsoft.AspNetCore.Mvc;
namespace CitiesManager.WebApi.Controllers
{
// এখানে কোনো [Route] বা [ApiController] লেখার দরকার নেই!
// ControllerBase এর বদলে CustomControllerBase ইনহেরিট করা হয়েছে
public class CitiesController : CustomControllerBase
{
[HttpGet]
public IActionResult GetCities()
{
// Base Class এর মেথড সরাসরি কল করা যাচ্ছে
string message = GetSuccessMessage("Get All Cities");
return Ok(new { Message = message, Data = "List of Cities" });
}
}
}
🏆 Best Practices for Custom Base Controllers
- Use
abstractKeyword: আপনার Base Controller ক্লাসটিকে সবসময়abstractহিসেবে ডিক্লেয়ার করবেন (যেমনটা উপরের কোডে দেখানো হয়েছে)। কারণ এই ক্লাসের নিজের কোনো স্বাধীন অস্তিত্ব নেই, এটি শুধুমাত্র অন্য ক্লাসকে ফিচার দেওয়ার জন্য তৈরি করা হয়েছে।abstractদিলে কেউ ভুল করে এর Object তৈরি করতে পারবে না। - Keep it Lightweight: Base Class-এর ভেতর খুব বেশি ডিপেন্ডেন্সি (যেমন: অনেকগুলো Service Inject করা) রাখবেন না। কারণ Base Class-এ কোনো ডিপেন্ডেন্সি থাকলে চাইল্ড ক্লাসের Constructor থেকে সেটি
base()কিওয়ার্ড দিয়ে পাঠাতে হয়, যা পরবর্তীতে মেইনটেইন করা বেশ ঝামেলার হয়ে যায়। - Naming Convention: ক্লাসের নামের শেষে
BaseবাControllerBaseরাখা ভালো প্র্যাকটিস (যেমন:ApiControllerBase), এতে অন্য ডেভেলপাররা নাম দেখেই বুঝতে পারে যে এটি কোনো সাধারণ Controller নয়।