স্বাগতম! আপনার কোর্সের Outline অনুযায়ী আমরা এখন Section 20 (Filters)-এর “IAlwaysRunResultFilter” (লেকচার ২৯৯) টপিকে চলে এসেছি।
আগের লেকচারগুলোতে আমরা দেখেছি, Authorization বা Exception Filter-এ যখন રিকোয়েস্ট শর্ট-সার্কিট (Short-circuit) করা হয়, তখন Result Filter কাজ করে না। কিন্তু যদি এমন কোনো কাজ থাকে যা আপনার অ্যাপ্লিকেশনকে অবশ্যই করতে হবে (যেমন— মেমরি ক্লিন করা বা ক্যাশ ডিলিট করা), রিকোয়েস্ট শর্ট-সার্কিট হলেও? এই সমস্যার সমাধানই হলো Always Run Result Filter। চলুন বিস্তারিত শেখা যাক!
📝 Quick Revision Summary
ভবিষ্যতে দ্রুত রিভিশন দেওয়ার জন্য পুরো লেকচারের মূল পয়েন্টগুলো নিচে দেওয়া হলো:
- The Problem: রিকোয়েস্ট যদি Authorization, Resource, বা Exception Filter-এ শর্ট-সার্কিট হয়ে যায়, তবে সাধারণ Result Filter এক্সিকিউট হয় না।
- The Solution:
IAlwaysRunResultFilterএকটি বিশেষ ধরনের Result Filter যা শর্ট-সার্কিট হওয়ার পরেও বাধ্যতামূলকভাবে (compulsory) রান করে। - কেন ব্যবহার করবেন: Memory Cleanup, Cache clear করা, Cookie রিমুভ করা, বা Performance metrics ক্লোজ করার মতো কাজের জন্য, যা ফেইল-সেফ হওয়া জরুরি।
- Interface: সিঙ্ক্রোনাসের জন্য
IAlwaysRunResultFilterএবং অ্যাসিন্ক্রোনাসের জন্যIAsyncAlwaysRunResultFilterব্যবহার করা হয়।
🔍 Comprehensive Breakdown
১. The Core Concept (কেন এই বিশেষ Filter?) [Priority: 10/10]
The “Why”: ধরুন, আপনার সিস্টেমে একটি Performance Tracker আছে যা রিকোয়েস্ট শুরু হলে টাইম কাউন্ট শুরু করে এবং রেসপন্স যাওয়ার সময় কাউন্ট বন্ধ করে লগ তৈরি করে। যদি কোনো ইউজার লগইন না করার কারণে Authorization Filter তাকে ব্লক (Short-circuit) করে দেয়, তবে সাধারণ Result Filter রান করবে না। ফলে আপনার টাইমারটি আর বন্ধ হবে না এবং সার্ভারে মেমরি লিক হতে পারে। এই ধরনের গ্যারান্টিড এক্সিকিউশনের জন্যই Always Run Result Filter ব্যবহার করা হয়। এটি সব বাধা বিপত্তি পেরিয়ে ঠিকই এক্সিকিউট হয়।
২. How it Works (Execution Flow) [Priority: 9/10]
- Authorization Short-circuit: সাধারণ Result Filter রান করে না। Always Run Result Filter রান করে।
- Resource Filter Short-circuit: সাধারণ Result Filter রান করে না। Always Run Result Filter রান করে।
- Exception Filter Short-circuit: সাধারণ Result Filter রান করে না। Always Run Result Filter রান করে।
- Action Filter Short-circuit: সাধারণ Result Filter এবং Always Run Result Filter দুটোই রান করে।
- Result Filter Short-circuit: Always Run Result Filter রান করে।
(সোজা কথায়: যে অবস্থাতেই রিকোয়েস্ট বাতিল হোক না কেন, Always Run Result Filter তার কাজ করবেই!)
৩. Code Implementation: Creating the Filter [Priority: 10/10]
এই ফিল্টারটির সিনট্যাক্স সাধারণ Result Filter-এর মতোই। শুধু ইন্টারফেসটির নাম ভিন্ন।
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
// IAlwaysRunResultFilter ইন্টারফেস ইমপ্লিমেন্ট করা হচ্ছে
public class PersonsAlwaysRunResultFilter : IAlwaysRunResultFilter
{
private readonly ILogger<PersonsAlwaysRunResultFilter> _logger;
public PersonsAlwaysRunResultFilter(ILogger<PersonsAlwaysRunResultFilter> logger)
{
_logger = logger;
}
public void OnResultExecuting(ResultExecutingContext context)
{
// ----------------------------------------------------
// BEFORE LOGIC (Executes before the result is written)
// ----------------------------------------------------
_logger.LogInformation("AlwaysRunResultFilter: OnResultExecuting called.");
// Example: Adding a compulsory security header
context.HttpContext.Response.Headers["X-Always-Run-Header"] = "Executed";
}
public void OnResultExecuted(ResultExecutedContext context)
{
// ----------------------------------------------------
// AFTER LOGIC (Executes after the result is written)
// ----------------------------------------------------
_logger.LogInformation("AlwaysRunResultFilter: OnResultExecuted called.");
// Example: Cache clearing or closing performance matrix
}
}
৪. Applying and Testing the Scenario [Priority: 9/10]
লেকচারার একটি চমৎকার ডেমো দিয়ে বুঝিয়েছেন:
- প্রথমে তিনি Controller-এর
EditHttpGetমেথড থেকেTokenResultFilter-টি কমেন্ট করে দেন। এর মানে হলো ব্রাউজারে আর কোনো Authentication Cookie যাবে না। - এরপর
EditHttpPostমেথডেPersonsAlwaysRunResultFilterঅ্যাপ্লাই করেন। - ফলাফল: যখন ফর্ম সাবমিট করা হয়, তখন
TokenAuthorizationFilterকুকি না পেয়ে 401 Unauthorized দিয়ে রিকোয়েস্ট Short-circuit করে দেয়। - Action Method বা সাধারণ Result Filter কিছুই রান করে না। কিন্তু ব্রেকপয়েন্ট ঠিকই
PersonsAlwaysRunResultFilter-এ এসে হিট করে!
public class PersonsController : Controller
{
// Authorization ফেইল করলেও এই ফিল্টারটি ঠিকই এক্সিকিউট হবে
[TypeFilter(typeof(PersonsAlwaysRunResultFilter))]
[HttpPost]
public IActionResult Edit(PersonUpdateRequest personRequest)
{
// ...
}
}
🚀 Best Practices & .NET Modern Updates
Best Practices for Always Run Result Filters:
- Rare Usage: লেকচারার যেমনটি বলেছেন, রিয়েল-ওয়ার্ল্ড প্রজেক্টে এই ফিল্টারের ব্যবহার বেশ বিরল। শুধুমাত্র গ্লোবাল ক্লিনআপ (Global Cleanup) বা মেট্রিক্স ট্র্যাকিংয়ের জন্যই এটি ব্যবহার করুন। সাধারণ লজিকের জন্য রেগুলার Result Filter-ই যথেষ্ট।
- Keep it Lightweight: যেহেতু এটি গ্যারান্টিড রান করবে (এমনকি এরর বা শর্ট-সার্কিট হলেও), তাই এর ভেতরে কখনোই ভারী ডেটাবেস অপারেশন করবেন না।
.NET 10 & API Context (The Modern Approach):
আপনি যদি .NET 10-এ Minimal APIs নিয়ে কাজ করেন, সেখানে আলাদা করে IAlwaysRunResultFilter ইন্টারফেস নেই। কিন্তু C#-এর ডিফল্ট try...finally ব্লক ব্যবহার করে খুব সহজেই এই “Always Run” মেকানিজম তৈরি করা যায়। এটি পারফরম্যান্সের দিক থেকেও অনেক ফাস্ট!
Minimal API “Always Run” Endpoint Filter Example (.NET 10):
app.MapPost("/api/persons/edit", () => Results.Ok("Updated"))
.AddEndpointFilter(async (context, next) =>
{
try
{
// Next ফিল্টার বা অ্যাকশনকে কল করা হলো
return await next(context);
}
finally
{
// 🚀 ALWAYS RUN LOGIC 🚀
// রিকোয়েস্ট শর্ট-সার্কিট হোক, এক্সেপশন থ্রো করুক, বা সফল হোক—
// finally ব্লকটি ১০০% গ্যারান্টি দিয়ে এক্সিকিউট হবে!
Console.WriteLine("Cleaning up resources unconditionally...");
}
});
আশা করি AlwaysRunResultFilter এর কনসেপ্ট এবং এর ব্যবহার আপনার কাছে পুরোপুরি পরিষ্কার হয়ে গেছে। আপনার কোর্স Outline অনুযায়ী পরবর্তী লেকচারে আমরা Filter Overrides নিয়ে আলোচনা করব।