Interceptor‌ها در دات نت

Interceptor‌ها در دات نت

به طور کلی، Interceptor‌ها در C# به منظور افزودن انعطاف‌پذیری به سیستم‌ها و چارچوب‌های نرم‌افزاری استفاده می‌شوند

در .NET 8، Interceptors به عنوان یک ویژگی جدید و قدرتمند در برنامه‌نویسی شیءگرا و به ویژه در زمینه Dependency Injection (DI) معرفی شده‌اند. این ویژگی به توسعه‌دهندگان این امکان را می‌دهد که به راحتی رفتار متدها را تغییر دهند و کد اضافی را قبل یا بعد از فراخوانی متدها اجرا کنند. در اینجا به تفصیل به Interceptors در .NET 8 می‌پردازیم:

1. تعریف Interceptors

در دات نت 8 به بعد  Interceptors  به شما این امکان را می‌دهند که کد اضافی (مانند لاگ‌گیری، اعتبارسنجی، مدیریت خطا و غیره) را به متدهای یک شیء اضافه کنید، بدون اینکه نیاز به تغییر در کد اصلی متدها باشد. این کار به شما کمک می‌کند تا از تکرار کد جلوگیری کنید و کد خود را تمیزتر و قابل نگهداری‌تر کنید.

2. ویژگی‌های کلیدی Interceptors در .NET 8

  • سازگاری با Dependency Injection: Interceptors به طور طبیعی با فریمورک‌های DI در .NET یکپارچه شده‌اند. این به این معنی است که می‌توانید Interceptors را به سادگی در زمان پیکربندی سرویس‌ها اضافه کنید.
  • پشتیبانی از AOP (Aspect-Oriented Programming): با استفاده از Interceptors، می‌توانید به راحتی جنبه‌های مختلف برنامه را مدیریت کنید، مانند لاگ‌گیری و اعتبارسنجی، که به شما این امکان را می‌دهد که نگرانی‌ها را از هم جدا کنید.
  • عملکرد بهینه: Interceptors در .NET 8 به گونه‌ای طراحی شده‌اند که عملکرد برنامه را تحت تأثیر قرار ندهند و به شما این امکان را می‌دهند که به راحتی رفتارهای مورد نظر خود را به متدها اضافه کنید.

3. پیاده‌سازی Interceptors

برای استفاده از Interceptors در .NET 8، شما باید یک کلاس Interceptor ایجاد کنید که رفتار مورد نظر شما را پیاده‌سازی کند. این کلاس باید از IInterceptor پیروی کند.

4. مزایا و معایب

مزایا:

  • جداسازی نگرانی‌ها: Interceptors به شما این امکان را می‌دهند که رفتارهای خاص را جدا کنید و کد خود را تمیزتر کنید.
  • قابلیت استفاده مجدد: می‌توانید Interceptors را در چندین قسمت از برنامه استفاده کنید.
  • کاهش تکرار کد: با استفاده از Interceptors، نیازی به تکرار کد برای رفتارهای مشابه در متدهای مختلف ندارید.

معایب:

  • پیچیدگی: ممکن است استفاده از Interceptors باعث پیچیدگی در درک جریان برنامه شود.
  • عملکرد: در برخی موارد، استفاده نادرست از Interceptors ممکن است بر عملکرد برنامه تأثیر بگذارد.

 

بیایید یک مثال کامل و دقیق از استفاده از Interceptors در .NET 8 ارائه دهیم و نشان دهیم که چگونه می‌توان یک Interceptor را برای یک متد خاص مشخص کرد. در این مثال، ما از فریمورک Castle DynamicProxy استفاده خواهیم کرد که به ما این امکان را می‌دهد که Interceptorها را به راحتی پیاده‌سازی کنیم.

مراحل پیاده‌سازی Interceptor

  1. نصب پکیج‌های لازم ابتدا باید پکیج Castle.Core را به پروژه خود اضافه کنید. می‌توانید این کار را با استفاده از NuGet Package Manager انجام دهید: 

Install-Package Castle.Core

  1. تعریف اینترفیس و کلاس اصلی

 

 

public interface IMyService

{
    void PerformAction();
}

public class MyService : IMyService

{
    public void PerformAction()

    {
        Console.WriteLine("Action performed.");
    }

}

 

 

  • اینترفیس IMyService: این اینترفیس متدی به نام PerformAction را تعریف می‌کند.
  • کلاس MyService: این کلاس پیاده‌سازی IMyService است و متد PerformAction را به گونه‌ای پیاده‌سازی می‌کند که فقط یک پیام را در کنسول چاپ کند.
  1. تعریف Interceptor

   

 

 

using Castle.DynamicProxy;



public class LoggingInterceptor : IInterceptor

{

    public void Intercept(IInvocation invocation)

    {

        Console.WriteLine("Before action");  // کد قبل از اجرای متد

        invocation.Proceed();                  // فراخوانی متد اصلی

        Console.WriteLine("After action");   // کد بعد از اجرای متد

    }

}

 

 

  • کلاس LoggingInterceptor: این کلاس از IInterceptor پیروی می‌کند و متد Intercept را پیاده‌سازی می‌کند. در این متد، ما می‌توانیم کدهایی را که قبل و بعد از اجرای متد اصلی اجرا می‌شود، قرار دهیم.
  1. پیکربندی Dependency Injection

حالا بیایید پیکربندی DI را انجام دهیم و مشخص کنیم که Interceptor برای متد خاصی (در اینجا PerformAction) فعال شود.

      

  using Microsoft.Extensions.DependencyInjection;



var services = new ServiceCollection();

var proxyGenerator = new ProxyGenerator();



// ثبت سرویس MyService به عنوان یک پروکسی با Interceptor

services.AddTransient<IMyService>(provider =>

    proxyGenerator.CreateInterfaceProxyWithTarget<IMyService>(

        new MyService(),

        provider.GetRequiredService<LoggingInterceptor>()));



services.AddTransient<LoggingInterceptor>();



var serviceProvider = services.BuildServiceProvider();

var myService = serviceProvider.GetService<IMyService>();

myService.PerformAction();

 

 

 

 

توضیح کد پیکربندی

  • ما از ProxyGenerator برای ایجاد یک پروکسی از MyService استفاده می‌کنیم. این پروکسی به ما این امکان را می‌دهد که Interceptor را به آن متصل کنیم.
  • متد CreateInterfaceProxyWithTarget  یک پروکسی از IMyService ایجاد می‌کند که به MyService متصل است و Interceptor (در اینجا LoggingInterceptor) را به آن اضافه می‌کند. این به این معنی است که هر بار که متد PerformAction فراخوانی می‌شود، Interceptor فعال می‌شود.

نتیجه نهایی

در نهایت، با اجرای کد، خروجی زیر در کنسول نمایش داده می‌شود:

   Before action

Action performed.

After action

جمع‌بندی

در این مثال، ما نشان دادیم که چگونه می‌توانیم یک Interceptor را برای یک متد خاص (در اینجا PerformAction) مشخص کنیم. با استفاده از CreateInterfaceProxyWithTarget، ما یک پروکسی ایجاد کردیم که Interceptor را به متد PerformAction متصل می‌کند. به این ترتیب، هر بار که این متد فراخوانی می‌شود، کدهای موجود در Interceptor (قبل و بعد از اجرای متد) نیز اجرا می‌شوند.

 

مرتضی جنگجو

برنامه نویس fullstack با بیش از 14 سال سابقه کار و همکاری در توسعه و پیاده سازی نرم افزارهای تحت وب با تکنولوژی Net. در شرکتهای بزرگ ایرانی، هلندی، فنلاندی و ترکیه

شبکه های اجتماعی نویسنده

دیدگاه کاربران