بررسی قابلیت میان افزار Middleware در ASP.NET Core

بررسی قابلیت میان افزار Middleware در ASP.NET Core

در این پست از وبسایت پرووید، در رابطه با بررسی قابلیت میان افزار Middleware در ASP.NET Core صحبت خواهیم کرد. به ادامه ی مطلب بروید.

در این قسمت از سری آموزش رایگان ASP.NET Core از وب سایت پرووید در رابطه با Middleware صحبت خواهیم کرد. در فریم ورک ASP.NET Core یک مفهوم جدید به نام Middleware معرفی شد. بطور ساده یک Middleware یک Component و یا یک کلاس است که به ازای هر Request که به درون اپلیکشن وارد می شود اجرا خواهد شد. در ASP.NET همین ماهیت توسط HttpHandler ها و HttpModule ها پیاده سازی می شد که هر دو بخشی از خط لولۀ درخواست و یا اصطلاحاً Request Pipeline بودند. منظور از خط لولۀ درخواست و یا Request Pipeline این است که به ازای هر Request که به درون اپلیکیشن وارد می شود یک سری عملیات اجرا می شوند که در کنار هم یک خط لوله و یا Pipeline را تشکیل می دهند.

بسته ی آموزش ویدئویی ساخت یک Enterprise Application با ASP.NET Core MVC

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی ساخت یک Enterprise Application با ASP.NET Core MVC دیدن کنید.

ماهیت Middleware در ASP.NET Core شبیه به HttpHandler ها و HttpModule ها در ASP.NET می باشد. از این نظر که همگی قابل پیکربندی هستند و به ازای هر Request که قرار است هندل بشود اجرا می شوند. بطور کلی در یک وب اپلیکیشن با ASP.NET Core چندین Middleware وجود خواهند داشت. در واقع Middleware ها می توانند توسط خود فریم ورک ASP.NET Core فراهم شوند و یا بصورت Custom و یا سفارشی توسط خود برنامه نویس ایجاد گردند. می توان بسادگی ترتیب اجرا شدن هر کدام از Middleware ها را در Request Pipeline تنظیم کرد. هر Middleware اقدام به تغییر دادن یک Http Request کرده و احتمالاً پس از آن اقدام به اجرا کردن Middleware Component بعدی می کند.

بسته ی آموزش ویدئویی ساخت وب اپلیکیشن با ASP.NET Core و React

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی ساخت وب اپلیکیشن با ASP.NET Core و React دیدن کنید.

تصویری که در قسمت زیر مشاهده می کنید روند اجرا شدن Middleware Component ها را نشان می دهد.

در واقع Middleware Component ها در کنار هم Request Pipeline را ایجاد می کنند. تصویر زیر روند پردازش یک Request در Request Pipeline را در فریم ورک ASP.NET Core را به تصویر کشیده است.

پیکر بندی Middleware ها

بسادگی می توان در ASP.NET Core اقدام به پیکر بندی Middleware ها کرد. اینکار با استفاده از متد Configure از کلاس Startup انجام می شود. همانطور که می دانید یکی از پارامترهای متد Configure یک IApplicationBuilder می باشد. کدی که در قسمت زیر مشاهده می کنید یک Middleware را با استفاده از متد Run به Request Pipeline اضافه کرده است.

public class Startup
{
    public Startup()
    {
    } 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        //configure middleware using IApplicationBuilder here..
            
        app.Run(async (context) =>
        {              
            await context.Response.WriteAsync("Hello World!");
              
        });

        // other code removed for clarity.. 
    }
}

این Middleware که بصورت بسیار ساده پیاده سازی شده است رشته ی Hello World را به ازای هر Request بر می گرداند. در کدی که در قسمت بالا مشاهده می کنید از متد Run به عنوان یک Extension Method برای IApplicationBuilder استفاده شده است. در رابطه با Extension Method ها توصیه می کنیم از آموزش کامل توسعه نرم افزار با سی شارپ استفاده کنید. متد Run به منظور اضافه کردن یک Middleware به Request Pipeline برنامه مورد استفاده قرار گرفته است.

بسته ی آموزش ویدئویی معماری پیازی و ساخت پروژه عملی با ASP.NET Core MVC

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی معماری پیازی و ساخت پروژه عملی با ASP.NET Core MVC دیدن کنید.

این Middleware بسادگی به ازای هر Request یک Response که در قالب یک داده ی String با محتوای Hello World می باشد را Return می کند.

درک بهتر متد Run

همانطور که مشاهده کردید در قسمت قبل با استفاده از Run اقدام به اضافه کردن یک Middleware کردیم. کدی که در قسمت زیر می بینید امضا و یا اصطلاحاً Signature مربوط به متد Run را نشان می دهد.

public static void Run(this IApplicationBuilder app, RequestDelegate handler)

همانطور که گفتیم متد Run یک Extension Method برای IApplicationBuilder می باشد که یک پارامتر ورودی از نوع RequestDelegate را دریافت می کند. بطور ساده RequestDelegate یک Delegate Method می باشد که به منظور Handle کردن Request مورد نظر، مورد استفاده قرار می گیرد. کد زیر Signature مربوط به RequestDelegate را نشان می دهد.

public delegate Task RequestDelegate(HttpContext context);

برای درک هرچه بهتر ماهیت Delegate ها توصیه می کنیم از آموزش ویدئویی Delegate ها در سی شارپ استفاده کنید.

همانطور که RequestDelegate نشان می دهد پارامتر ورودی متد Run که از نوع Delegate می باشد باید با امضا و یا اصطلاحاً Signature مربوط به RequestDelegate تطابق داشته باشد. به عبارت دیگر این متد باید یک Object از نوع HttpContext را به عنوان پارامتر قبول کرده و یک Task را Return کند.

از آنجایی که پارامتر ورودی متد Run یک RequestDelegate است شما هم می توانید یک Lambda Expression به عنوان ورودی برای متد Run تنظیم کنید و یا یک متد را تعریف کرده و نام آن را به عنوان پارامتر ورودی متد Run تنظیم کنید. در رابطه با Lambda Expression ها توصیه می کنیم از آموزش ویدئویی Lambda Expression در سی شارپ استفاده کنید.

در مثال قبلی یک Lambda Expression به عنوان پارامتر ورودی متد Run تنظیم شد که شبیه به کد زیر عمل می کند.

public class Startup
{
    public Startup()
    {
    } 

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
         app.Run(MyMiddleware);
    }

    private Task MyMiddleware(HttpContext context) 
    {
        return context.Response.WriteAsync("Hello World! ");
    }
}

در کد زیر بجای تعریف یک Lambda Expression از یک متد به نام MyMiddleware که با Delegate مورد نظر تطابق دارد استفاده شده است. همانطور که مشاهده می کنید. متد MyMiddleware بصورت Asynchronous تعریف نشده است. بنابراین تا زمان کامل نشدن عملیات مورد نظرش Thread جاری را متوقف می کند. اگر بخواهیم این متد بصورت Asynchronous اجرا بشود باید از کلمات کلیدی async و await استفاده کنیم. این موضوع باعث می شود که Performance و Scalability و یا اصطلاحاً کارایی و مقیاس پذیری برنامه افزایش پیدا کند. کد زیر این موضوع را نشان می دهد.

// other code removed for clarity

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
     app.Run(MyMiddleware);
}

private async Task MyMiddleware(HttpContext context) 
{
    await context.Response.WriteAsync("Hello World! ");
}

ضمناً توصیه می کنیم به منظور درک هر چه بهتر برنامه نویسی همروند و یا اصطلاحاً  Asynchronous Programing از بسته ی آموزش ویدئویی برنامه نویسی چند نخی در سی شارپ از وب سایت پرووید استفاده کنید.

علاوه بر این می توانیم همین کار را در قالب یک Lambda Expression نیز پیاده سازی کنیم. کد زیر این موضوع را نشان می دهد.

app.Run(async context => await context.Response.WriteAsync("Hello World!") );

//or 

app.Run(async (context) =>
{
    await context.Response.WriteAsync("Hello World!"); 
});

بنابراین توانستیم با استفاده از متد Run یک Middleware را به راحتی پیکر بندی کنیم.

پیکر بندی چندین Middleware

همانطور که قبلاً نیز گفتیم در یک Web Application با ASP.NET Core چندین Middleware Component مختلف وجود خواهند داشت که یکی پس از دیگری بصورت ترتیبی اجرا خواهند شد. متد Run که در قسمتهای قبلی آن را بررسی کردیم اصطلاحاً یک Terminal Middleware و یا یک Middleware نهایی به برنامه اضافه خواهد کرد. این به این معنی است که Middleware Component اضافه شده توسط متد Run نمی تواند Middleware Component دیگری را صدا بزند، چرا که آخرین Middleware Component خواهد بود. کدی که در قسمت زیر مشاهده می کنید اقدام به اجرا کردن یک Middleware Component با متد Run کرده و Middleware Component بعدی که توسط متد Run اضافه شده است هرگز اجرا نخواهد شد.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World From 1st Middleware"); 
    });
    
    // the following will never be executed
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World From 2nd Middleware"); 
    });
}

چرا که با استفاده از متد Run می توان فقط یک Terminal Middleware و یا اصطلاحاً یک Middleware Component نهایی را اضافه کرد. همانطور که می دانید معنی کلمۀ Terminal در زبان انگلیسی به معنی آخرین می باشد. به منظور اضافه کردن یک Middleware Component دیگر که بتواند Middleware Component بعدی را نیز صدا بزند از یک Extension Method به نام Use() استفاده می کنیم. نحوۀ استفاده کردن از این متد شبیه به متد Run() می باشد با این تفاوت که پارامتر دوم این متد نمایانگر Middleware Component بعدی که باید اجرا بشود است. کدی که در قسمت زیر مشاهده می کنید نحوه ی استفاده کردن از متد Use() را نشان می دهد.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Use(async (context, next) =>
    {
        await context.Response.WriteAsync("Hello World From 1st Middleware!");

        await next();
    });

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World From 2nd Middleware"); 
    });
}

کدی که در قسمت بالا مشاهده کردید رشتۀ Hello World From 1st Middleware! Hello World From 2nd Middleware! را در مرورگر نشان خواهد داد. بنابراین ما می توانیم با استفاده از متد Use() اقدام به پیکر بندی کردن چندین Middleware Component با ترتیب مورد نظرمان کنیم.

اضافه کردن Middleware Component های Built-in با استفاده از NuGet

همانطور که تا اینجای کار درک کرده اید فریم ورک ASP.NET Core کاملاً ماژولار ساخته شده است. به عبارت دیگر می توانیم قابلیت های مختلف را زمانیکه به آنها نیاز داریم به برنامه اضافه کنیم. با استفاده کردن از پکیج های مربوط به NuGet می توانیم قابلیتهای Server-side مورد نظرمان را براحتی به برنامه اضافه کنیم. نکته اینجاست که بسیاری از Middleware Component ها در قالب پکیج های NuGet از قبل تعریف شده اند که می توانیم آنها را به برنامه اضافه کنیم لیستی از Middleware Component های Built-in و یا اصطلاحاً تعبیه شده در ASP.NET Core را در جدول زیر مشاهده می کنید.

به عنوان یک مثال بیایید از Middleware Component ای بنام Diagnostics استفاده کنیم.

استفاده کردن از Diagnostics Middleware

در این قسمت قصد داریم از Diagnostics بعنوان یک Built-in Middleware استفاده کنیم. این Middleware بمنظور گزارش کردن و هندل کردن Exception ها و Error ها در ASP.NET Core و همچنین Migration های مربوط به Entity Framework Core استفاده می شود. در ابتدا اقدام به اضافه کردن پکیج Microsoft.AspNetCore.Diagnostics با استفاده از NuGet کنید. در رابطه با استفاده کردن از NuGet توصیه می کنیم از آموزش ویدئویی NuGet در دات نت استفاده کنید. جدول زیر Middleware Component های مربوط به پکیج Microsoft.AspNetCore.Diagnostics و Extension Method می باشد.

حال می توانیم بسادگی در متد Configure از کلاس Startup و همچنین Extension Method های Use() و Run() که تا به اینجای کار با آنها آشنا شده اید از Middleware Component های موجود در این پکیج استفاده کنیم. برای مثال فرض کنید که می خواهیم از یک Middleware Component با نام WelcomePage که بمنظور نشان دادن یک صفحه خوش آمد گویی مورد استفاده قرار می گیرد استفاده کنید این موضوع در کد زیر نشان داده می شود.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{   
    app.UseWelcomePage(); 
    //other code removed for clarity 
}

حال با اجرا کردن برنامه به ازای هر Request که به درون برنامه وارد می شود یک پنجرۀ خوش آمد گویی شبیه به تصویر زیر به کاربر نشان داده خواهد شد.

این آموزش را در همین قسمت به پایان میرسانیم و در قسمت بعدی از این آموزش در رابطه با قابلیت Logging در فریم ورک ASP.NET Core و Web Application هایی که با این فریم ورک ساخته می شوند صحبت خواهیم کرد.

امیدواریم که این آموزش از وبسایت پرووید نیز مورد توجه تمامی دوستان عزیز قرار گرفته باشد. از شما دعوت می‌کنیم که از دیگر آموزش های ما در رابطه با فریم ورک ASP.NET Core استفاده کنید. لیست کامل این آموزش ها را می توانید در پست مربوط به آموزش کامل توسعه وب اپلیکیشن با ASP.NET Core مشاهده کنید.

مرتضی گیتی
بدون نظر

ارسال نظر

نظر
نام
ایمیل
وب سایت