حسین احمدی
بنیانگذار توسینسو و برنامه نویس و توسعه دهنده ارشد وب

ASP.NET Core چیست؟ معرفی امکانات به زبان بسیار ساده

ASP.NET Core چیست؟ مایکروسافت مدتی هست که اقدام به انتشار نسخه جدید از ASP.NET مبتنی بر DotNet Core کرده که به همین خاطر به اون ASP.NET Core گفته میشه. ASP.NET Core از ابتدا باز نویسی شده تا امکانات بیشتری (علی الخصوص Cross Platform) بودن رو برای توسعه دهنده ها فراهم کنه. در این مطلب قصد داریم تا کمی با این پلتفرم آشنا بشیم و تفاوت های اون رو با ASP.NET MVC بررسی کنیم.

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران

اگر شما قبلاً با ASP.NET MVC کار کرده باشید، زمان استفاده از ASP.NET Core، شاید در قدم اول کمی سردرگم بشید. همون اتفاقی که برای منم افتاد. درسته که خیلی از بخش های ASP.NET Core با ASP.NET MVC مشترکه (مثل Controller ها، View ها، ایجاد Area ها و ...)، اما تغییرات بنیادی زیادی هم بوجود اومده که نیاز پیدا می کنید تا کمی برای آشنایی با اون مطالعه داشته باشید.

ساختاری شبیه به برنامه های کنسول

در ASP.NET MVC شما یک Web Application ایجاد می کردید که این پروژه یک فایل global.asax.cs در اختار شما میزاشت و داخل این فایل تقریباً Pipeline درخواست های برنامه رو می تونستید مدیریت کنید. در کنار این ها یک فایل web.config هم داشتید که تنظیمات Application داخل اون اعمال می شد. اما با ایجاد یک برنامه ASP.NET Core شما با یک فایل Program.cs که داخلش یک متد Main هست (مثل برنامه های Console) روبرو می شید. این فایل در نقطه شروع Application شماست که وظیفه پیکربندی وب سرور و بعد اجرای برنامه شما رو داره. در زیر نمونه ای از کد یک فایل Program.cs رو مشاهده می کنید:


public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup();


بخشی که در این کد باید بهش دقت کنیم، قسمت UseStartup هست که شما باید کلاس Startup رو مشخص کنید. وظیفه کلاس Startup مشخص کردن Dependency های برنامه (برای بحث IoC و DI) و همچنین مشخص کردن Middleware ها برای مدیریت Request هاست. کد زیر یک فایل اولیه Startup.cs رو نشون میده:


public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

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


در کد بالا دو متد وجود داره، متد ConfigureServices که برای تعیین Dependency ها و تعریف سرویس ها مورد استفاده قرار میگیره و متد Configure که برای مشخص کردن Middleware ها استفاده میشه. در بخش های بعدی در مورد Middleware ها صحبت می کنیم.


Middleware ها به جای HttpModules و HttpHandlers

اگر پیش زمینه استفاده از ASP.NET MVC رو داشته باشید، حتماً با واژه های Http Module و Http Handler آشنایی دارید. کدهایی که در طول اجرای یک درخواست به برنامه شما اجرا می شوند، برای مثال، شما در ASP.NET MVC می تونستید کدهایی رو در بخش هایی مثل Session_Start یا Begin_Request بنویسید که در قابل اجرا در مراحل مختلف پردازش یک درخواست بودند. اما در ASP.NET Core دیگه خبری از ماژول ها و هندلر ها نیست و شما باید از Middleware ها استفاده کنید.

Middleware یک کلاس هست که درخواست کاربر وارد کلاس شده پردازش میشه و به مرحله بعد منتقل میشه. به طور کلی ساختار پردازش درخواست ها در برنامه های ASP.NET Core، یکسری Middleware ها به صورت پشت سر هم هست که درخواست ها به ترتیب وارد Middleware ها شده تا به آخرین Middleware برسه و بعد دباره روند معکوس طی می کنه تا پاسخ به کاربر برگرده. داخل ASP.NET Core شما هم می تونید Middleware های که به صورت پیش فرض وجود دارن رو استفاده کنید و هم Middleware های مورد نظر خودتون رو تعریف کنید. کد زیر ساختار اولیه یک کلاس Middleware رو نشون میده:


public class MyMiddleware
{
    private readonly RequestDelegate next;

    public MyMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // code before next middleware
        await next(context);
        // code after next middleware
    }
}


در کد بالا، بخش هایی که به صورت کامنت نوشته شدن، کدهایی هستند که قبل از اجرای Middleware بعدی و قبلی اجرا میشن. برای استفاده از یک Middleware باید اون رو داخل متد Configure کلاس Startup تعریف کنید:


if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

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


خداحافظی با web.config

در برنامه های ASP.NET MVC ما یک فایل web.config داشتیم که وظیفه اون پیکربندی برنامه ها بود، مثل تعریف Connection String ها، تنظیمات Cookie ها و ...، در ASP.NET Core دیگه ما با فایلی به نام web.config کار نداریم و این فایل با فایل هایی مبتنی بر json جایگزین شدن که شما تنظیمات برنامه رو در قالب json تعریف می کنید. این فایل با نام appsettings.json تعریف میشه و محتویاتی شبیه به کد زیر داره:


{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}


برای مثال، شما اگر قصد تعریف Connection String مورد نظرتون رو دارید به صورت زیر می تونید داخل فایل json اون رو تعریف کنید:


{
  "ConnectionStrings": {
    "TosinsoDatabase": "Data Source=.; Initial Catalog=TosinsoDb; Integrated Security=true" 
  },
  ...


و برای استفاده از تنظیمات تعریف شده از اینترفیس IConfiguration باید استفاده کرد. کد نمونه زیر برای دریافت Connection String داخل یک Controller:


public class HomeController : Controller
{
    public HomeController(IConfiguration configuration)
    {
        var connectionString = configuration["ConnectionStrings:TosinsoDatabase"];
    }
}


وب سرور Kestrel به جای IIS

در برنامه های ASP.NET Core، شما به جای IIS از وب سرور جدیدی با نام Kestrel برای میزبانی برنامه ها استفاده می کنید. Kestrel یک وب سرور Open Source و البته Cross Platform هست که به شما این اجازه رو میده تا برنامه های ASP.NET Core رو بر روی پلتفرم های مختلف مثل ویندوز، لینوکس و ... اجرا کنید. وب سرور Kestrel در محیط Command Line قابل دسترس هست و مثل IIS رابط گرافیکی در اختیار شما نمیزاره. البته نکته ای رو اینجا باید بگم که شما می تونید از وب سرورهای دیگه مثل IIS یا NGINX به عنوان Reverse Proxy استفاده کنید، یعنی درخواست کاربر توسط وب سروری مثل IIS دریافت میشه، به وب سرور Kestrel منتقل میشه، عملیات پردازش درخواست انجام میشه و نتیجه برای انتقال به کاربر به IIS منتقل میشه. اگر شما از وب سرور IIS به عنوان Reverse Proxy استفاده کنید، داخل پوشه اصلی برنامه یک فایل web.config مشاهده خواهید کرد که این فایل ارتباطی به تنظیمات اصلی برنامه نداره و تنها توسط IIS استفاده میشه.

یک پروژه برای Web API و Web Application

در نسخه های قبلی ASP.NET برای نوشتن Web API شما نیاز به تعریف یک پروژه جداگانه برای Web API داشتید. اما در ASP.NET Core شما یک پروژه ایجاد می کنید و می توانید هم API داخل آن بنویسید و هم کدهای مربوط به Application. برای مثال، فرض کنید داخل پروژه ایجاد شده یک Controller برای نمایش View به کاربر دارید:


public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}


برای نوشتن یک Api کافیست یک Controller ایجاد کنید که به جای کلاس Controller از کلاس ControllerBase مشتق شده است و Api مورد نظرتون رو به صورت زیر ایجاد کنید:


public class ApiController : ControllerBase
{
    public ActionResult GetUser(long id)
    {
        return new User(){Id = 12, Username = "Hossein"}
    }
}


پوشه ای با نام wwwroot

در ASP.NET Core شما با پوشه ای روبرو هستید با نام wwwroot. کار این پوشه نگهداری فایل های static پروژه شما هست. یعنی شما تصویرها، فایل های js و استایل ها (css) رو داخل این پوشه قرار میدید. در نسخه های قبلی شما کافی بود فایل های مورد نظرتون رو داخل پوشه اصلی برنامه قرار بدید، اما داخل ASP.NET Core فایل هایی که خارج از پوشه wwwroot باشند به صورت مستقیم قابل دسترس نیستند. برای اینکه امکان دسترسی به فایل های static فراهم بشه، باید Middleware مربوط به این قابلیت رو اضافه کنید:


app.UseStaticFiles();


بخش مربوط به فایل های static تنظیمات زیادی داره که در مطلبی جداگانه در موردش توضیح خواهیم داد.


مدیریت Dependency های پروژه

در نسخه های قبلی ASP.NET ما از Nuget برای اضافه کردن Dependency ها به پروژه استفاده می کردیم. در ASP.NET Core راهکارهای مختلفی علاوه بر Nuget در اختیار ما قرار گرفته. مهمترین بخش استفاده از npm برای Package Management هست. یعنی شما می تونید بوسیله npm پکیج های مورد نظرتون رو به پروژه اضافه کنید. در کنار این موضوع امکان استفاده از ابزار جدید به نام Libman که مخفف Library Management هست در اختیار شما قرار گرفته تا بتونید Dependency های مورد نظرتون رو به پروژه هاتون اضافه کنید.

شاید در ابتدا این موضوع کمی گیج کننده باشه. اما به مرور بهش عادت می کنید.


وجود DI و IoC در همه قسمت های برنامه

یکی از بهترین بخش های ASP.NET Core این هست که توسعه دهنده مجبور به رعایت یکسری اصول در کدنویسی خودش میشه که مهمترینش IoC و DI هست. در هر جای پروژه تعریف Dependency ها به صورت Interface و استفاده از اون ها در به صورت DI به چشم میاد. شما هر سرویسی که میخوایید استفاده کنید رو باید با استفاده از Interface ها تعریف کنید و در متد ConfigureServices در کلاس Startup اون رو به DI Container اضافه کنید. در متد ConfigureServices امکان مشخص کردن تنظیمات تمامی بخش های برنامه وجود داره. برای مثال، فرض کنید کلاسی نیاز داریم که ارسال ایمیل رو برامون انجام بده. برای اینکار ابتدا یک interface به صورت زیر تعریف می کنیم:


public interface IEmailService
{
    void SendEmail(string to, string title, string message);
}


در قدم بعدی کلاس مورد نظر رو به صورت زیر تعریف می کنیم:


public class EmailService : IEmailService
{
    public void SendEmail(string to, string title, string message)
    {
        // code to send email
    }
}



سرویس تعریف شده رو در متد ConfigureServices به صورت زیر اضافه می کنیم:


public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IEmailService, EmailService>();
}


حالا برای استفاده از این کلاس داخل یک Controller کافیه کد زیر رو بنویسیم:


public class ContactController : Controller
{
    IEmailService emailService;
    public ContactController(IEmailService emailService)
    {
        this.emailService = emailService;
    }
    public IActionResult Reply()
    {
        emailService.Send("aaa@aaa.com","Title","Message");
    }
}

اضافه کردن سرویس ها حالت های مختلفی داره که در مطلبی جداگانه در مورد این بخش و حالت های مختلف اضافه کردن سرویس ها صحبت می کنیم.


حسین احمدی
حسین احمدی

بنیانگذار توسینسو و برنامه نویس و توسعه دهنده ارشد وب

حسین احمدی ، بنیانگذار TOSINSO ، توسعه دهنده وب و برنامه نویس ، بیش از 12 سال سابقه فعالیت حرفه ای در سطح کلان ، مشاور ، مدیر پروژه و مدرس نهادهای مالی و اعتباری ، تخصص در پلتفرم دات نت و زبان سی شارپ ، طراحی و توسعه وب ، امنیت نرم افزار ، تحلیل سیستم های اطلاعاتی و داده کاوی ...

نظرات