در باب (NET (Core. - قسمت دوم

به دنیا سلام کن ...در عنوان و متن این نوشته، اگر جایی کلمه ی core نوشته شده، در پرانتز قرار گرفته، به این علت که از ماه نوامبر سال 2020، مایکروسافت کلمه ی core را حذف کرد و NET 5. را منتشر کرد. ولی به جهت اهمیت تفکیک اسامی، من در این نوشته - بعضی جاها - از عبارت NET Core. استفاده کرده ام تا از NET Framework. جدا شود.برنامه نویس ها، زمانی که قصد یاد گرفتن یک زبان جدید را دارند، با یک برنامه ی خیلی ساده شروع می کنند که تنها یک متن در خروجی نمایش می دهد: Hello Worldاین یک رسم در دنیای برنامه نویسی است، و ما هم می خواهیم به همین رسم، یک کنسول اپلیکیشن ساده، با استفاده از NET Command-Line Interface. یا CLI، بسازیم و deploy کنیم.اگر هیچ آشنایی با NET (Core). ندارید، خواندن قسمت اول به فهم بهتر این مطلب کمک می کند:آشنایی با NET Core.نصب NET SDK.اولین قدم برای شروع، دانلود و نصب NET SDK. است.برای دانلود NET SDK. یک آدرس خیلی سرراست وجود دارد: https://dot.netکلمه SDK کوتاه شده ی عبارت Software Development Kit است. Kit، به مجموعه ای از آیتم ها گفته می شود، که برای انجام کار مشخصی، یا برای رسیدن به یک هدف استفاده می شوند. یکی از Kit های معروف، که همه می شناسیم First Aid Kit است که مجموعه ای از وسایل مورد استفاده در کمک های اولیه ست، که همه در یک بسته قرار گرفته اند.قطعا برای نوشتن نرم افزار هم یک سری ابزار، library، سند، نمونه کد و ... وجود دارد که به برنامه نویس ها اجازه می دهد در یک platform بخصوص، نرم افزار تولید کنند. به همین دلیل، زمانی که می خواهیم شروع کنیم به ایجاد یک نرم افزار تحت یک platform خاص، باید ابتدا SDK مناسب رو تهیه کنیم که ابزار لازم را برای تولید نرم افزار، در اختیارمان بگذارد.با مراجعه به آدرسی که معرفی شد، امکان دانلود SDK برای سیستم عامل های مختلف وجود دارد:ساخت یک کنسول اپلیکیشنیک نمونه برنامه ی Hello World ساده در NET SDK. وجود دارد که دستورالعمل ساخت آن را با هم می بینیم:در این نوشته، برای ساخت و اجرای برنامه ها، از CLI استفاده می کنیم. ولی همه ی این عملیات، با VisualStudio هم قابل انجام است.اگر تصمیم گرفتید که از CLI استفاده کنید، فقط دو ابزار زیر را لازم دارید:1. Command Line (در ویندوز کافی است یک command prompt باز کنید)2. text editor (برای مثال notepad در ویندوز)فرض کنیم می خواهیم یک فولدر به اسم DotNetConsoleSample ایجاد کنیم و فایل های اپلیکیشن را در آن قرار دهیم. برای این کار می توانیم از امکانات ویندوز برای ساختن فولدر استفاده کنیم، یا این که یک cmd باز کنیم و دستورهای زیر را تایپ کنیم:mkdir DotNetConsoleSample cd DotNetConsoleSampleیک فولدر با نام DotNetConsoleSample ساخته شد و working directory را تغییر دادیم به همین فولدر.تا اینجا هنوز با دستورهای dotnet کار نکرده ایم، اولین دستور:dotnet new consoleدستور dotnet new console یک کنسول اپلیکیشن Hello World در فولدر جاری می سازد. اگر محتویات فولدر را نگاه کنیم این دو فایل را می بینیم:Program.csDotNetConsoleSample.csprojمحتویات فایل Program.cs:using System; namespace DotNetConsoleSample { class Program { static void Main(string[] args) { Console.WriteLine(&quotHello World!&quot); } } }همان طور که مشخص است، این برنامه فقط یک عبارت Hello World نمایش می دهد.و فایل DotNetConsoleSample.csproj: (دقت کنید که فایل csproj همنامِ فولدرِ پروژه است)<Project Sdk=&quotMicrosoft.NET.Sdk&quot> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> </Project>فایل csproj در واقع توصیف کننده ی پروژه است. به صورت پیش فرض، همه ی فایل ها و subfolder هایی که در فولدر پروژه قرار دارند، در این فایل include هستند.اگر قبلا با NET Framework. کار کرده باشید، احتمالا متوجه یک تفاوت مهم شده اید. در NET Framework. لیست همه ی فایل های پروژه، در فایل csproj وجود داشت، در نتیجه اگر پروژه بزرگ بود و تعداد فایل های زیادی داشت، فایل csproj خیلی شلوغ می شد.ولی در NET (Core). تنها در صورتی که فایلی وجود دارد که در بیرون از فولدر پروژه است، باید آن را به فایل csproj. معرفی کنیم.با این حال، هنوز هم یک سری اطلاعات در فایل csproj. قرار می گیرد. برای مثال:1. مشخص کردن نسخه ی framework این برنامه:<PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup>یا اگر می خواهید چندین نسخه مشخص کنید:<PropertyGroup> <TargetFrameworks>netcoreapp3.1;net462</TargetFrameworks> </PropertyGroup>2. اگر می خواهید برنامه ای که نوشته اید را به صورت یک package منتشر کنید:<PropertyGroup> <PackageId>ClassLibDotNetStandard</PackageId> <Version>1.0.0</Version> <Authors>John Doe</Authors> <Company>Contoso</Company> </PropertyGroup>3. برای مشخص کردن فایلی که خارج از فولدر پروژه است:<ItemGroup> <Content Include=&quot..\Extras\**\*.cs&quot LinkBase=&quotShared&quot/> </ItemGroup>4. مشخص کردن یک نسخه ی خاص از زبان برنامه نویسی (برای مثال C# preview):<PropertyGroup> <LangVersion>preview</LangVersion> </PropertyGroup>5. فعال کردن، یا تعیین نوعِ قوانینِ کیفیتِ کد (Code quality rules):<PropertyGroup> <AnalysisMode>AllEnabledByDefault</AnalysisMode> </PropertyGroup>اگر نمی دانید که analyzer چیست:از NET 5.، مایکروسافت، analyzer های کد را به NET SDK. اضافه کرد. این analyzer ها قبلا هم وجود داشتند ولی در صورت نیاز، باید جداگانه نصب می شدند. در SDK جدید، نیاز به نصب جداگانه نیست و به صورت پیش فرض، فعال هستند.این analyzer ها می توانند هنگام کامپایل یا هنگام ویرایش کد، از دو جهت کد را بررسی کنند و در صورت نیاز خطا یا هشدار نشان دهند:1. سبک نوشتن کد2. کیفیت کداین ها چند نمونه از آیتم ها و ویژگی های فایل csproj. بود. لیست کامل را اینجا ببینید:https://docs.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-propsدستورهای dotnetما تا اینجا فقط از دستور dotnet new console برای ساخت یک کنسول اپلیکیشن استفاده کردیم، ولی دستور dotnet new امکانات دیگری هم دارد. برای نمونه:dotnet new classlib Creates a Class library.dotnet new wpf Creates a WPF Application.dotnet new worker Creates a Worker Service.dotnet new mstest Creates an Unit Test Project.dotnet new xunit Creates a xUnit Test Project.dotnet new web Creates a ASP.NET Core Empty.dotnet new mvc Creates a ASP.NET Core Web App.dotnet new angular Creates a ASP.NET Core with Angular.dotnet new grpc Creates a ASP.NET Core gRPC Service.dotnet new webconfig Creates a Web Config.dotnet new sln Creates a Solution File.لیست کامل را اینجا ببینید:https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-newدستور restoreبرای restore کردن package ها از فرمان زیر استفاده می کنیم:dotnet restoreهمچنین، CLI با اجرای دستورهای زیر، به صورت اتوماتیک، restore هم اجرا می کند:dotnet newdotnet builddotnet build-serverdotnet rundotnet testdotnet publishdotnet packاگر نمی دانید منظور از restore کردن پکیج ها چیست:یک ابزار مهم که هر platform برنامه نویسی باید داشته باشد، ابزاری است که به برنامه نویس ها اجازه دهد کدهایی را که می نویسند به اشتراک بگذارند. یعنی اگر یک برنامه نویس، یک کد reusable و مفید می نویسد، که احتمالا برای بقیه قابل استفاده است، آن را pack کرده و به صورت یک package، در اختیار بقیه قرار دهد. این package ها معمولا شامل کد کامپایل شده (dll) و یا سایر فایل های مرتبط با اون کد هستند.برای NET.، مایکروسافت یک مکانیزم اشتراک گذاری کد فراهم کرده، به اسم NuGet، که همه ی کارهای مربوط به ساخت پکیج ها و استفاده از آن توسط دیگران را انجام می دهد. NuGet یک repository مرکزی دارد که همه ی package ها آنجا قرار دارند و می توانند توسط برنامه نویس های NET. استفاده شوند.مثلا اگر نیاز داشته باشیم که برای Serialize کردن object ها، از Newtonsoft.Json استفاده کنیم این دستور را اجرا می کنیم:dotnet add package Newtonsoft.Jsonبا اجرای این دستور، پکیج مربوط به Newtonsoft.Json به پروژه اضافه شده و می توانیم از امکانات آن استفاده کنیم.بعد، هربار که دستور dotnet restore را اجرا می کنیم، NuGet دو فایل را برای پیدا کردن dependency ها چک می کند:فایل csproj.فایل packages.configبعد از پیدا کردن dependency ها، آن ها را، به همراه وابستگی های آن ها، دانلود کرده و داخل یک فولدر قرار می دهد. این که از کجا دانلود کند و در چه فولدری ذخیره کند، همه قابل configure کردن هستند.در نتیجه دیگر نیازی به دانلود dll مربوط به کامپوننت هایی که نیاز داریم اضافه کردن آنها به reference های پروژه نیست. فقط برای اضافه کردن dependency ها به پروژه از یک دستور استفاده می کنیم و با هر بار build یا run ، نسخه ی مناسبِ این پکیج -اگر لازم باشد- restore شده و امکانات آن قابل استفاده است. از این جا به بعد، همه ی کارهای مربوط به package ها، مثل مدیریت آپدیت شدن نسخه ها و ... را NuGet انجام می دهد.اجرای برنامه:برای اجرای برنامه، کافیست در cmd این دستور را اجرا کنیم:dotnet runنگران بیلد شدن برنامه نباشید، dotnet ، هر زمان لازم باشد بیلد را انجام خواهد داد.با این حال، دستور build هم وجود دارد:dotnet buildبعد از اجرای dotnet run، برنامه باید عبارت Hello World را نمایش دهد: ساخت یک وب اپلیکیشنبرای برنامه های وب هم، مثل کنسول اپلیکیشن، یک نمونه برنامه ی Hello World وجود دارد. این برنامه وقتی اجرا شود، یک سرویس HTTP می سازد، که در پاسخ به یک GET Request، عبارت Hello World را برمی گرداند.دستور ساختن یک وب اپلیکیشن:dotnet new webبعد از اجرای این دستور، علاوه بر فایل های Program.cs و csproj.، یک فایل نام Startup.cs هم ساخته می شود. ASP.NET برای مدیریتِ نحوه ی پاسخگویی به request ها، از این کلاس استفاده می کند.در این برنامه، Program.cs دو وظیفه بر عهده دارد:وظیفه ی start کردن وب سرور وظیفه ی start کردن وب اپلیکیشنفایل Program.cs:public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }همانطور که مشخص است، وقتی سرور شروع به کار می کند، از کلاس برای start کردن اپلیکیشن، از کلاس Startup استفاده می کند.اگر برای این برنامه، دستور زیر را اجرا کنیم:dotnet runوب اپلیکیشن روی port مشخص، آماده ی جواب دادن به request هاست. کافی است browser را باز کرده و به آدرس مشخص شده در تصویر بالا مراجعه کنیم:پابلیش اپلیکیشنطراحی NET (Core). به گونه ای است که، deploy کردن اپلیکیشن، به سادگیِ کپی کردن چند فایل باشد.در NET CLI. این امکان وجود دارد، که همه ی binary های مورد نیاز برای پابلیش اپلیکیشن، در یک فولدر جمع آوری شود. کافی است دستور زیر را اجرا کنیم:dotnet publish -c Releaseدقت کنید که در دستور بالا، Release نام فولدری است که می خواهید فایل های برنامه در آن قرار بگیرند. این فایل ها را روی یک سیستم دیگر که NET SDK. روی آن نصب است کپی کنید و سپس دستور زیر را (از همان فولدر) اجرا کنید:dotnet DotNetConsoleSample.dllبه این روشِ پابلیش، framework-dependent deployment گفته می شود. یعنی وقتی فایل ها را روی سیستمِ مقصد کپی می کنیم، برای اجرای برنامه، باید NET SDK. روی آن سیستم موجود باشد.اگر می خواهیم بدون نیاز به NET SDK. برنامه را اجرا کنیم باید از روش self-contained application استفاده کنیم. ابتدا باید در فایل csproj. مشخص کنیم که نرم افزار روی چه runtime ای قابلیت اجرا دارد:<Project Sdk=&quotMicrosoft.NET.Sdk&quot> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> <RuntimeIdentifiers>win10-x64;osx.10.11-x64;linuxmint.17.1x64</RuntimeIdentifiers> </PropertyGroup> </Project>و دستور زیر را اجرا می کنیم:dotnet publish -c Release -r linuxmint.17.1-x64با این روش، تمام فایل های مورد نیاز برای اجرای برنامه، شامل dll های dotnet، در فولدر مشخص شده قرار می گیرند. همچنین اگر پروژه شامل package خاصی باشد، فایل های آن هم در این فولدر کپی خواهد شد.بنابراین این فولدر، می تواند روی هر ماشینی کپی شده و بدون نیاز به SDK اجرا شود.مشکل محیط توسعه نرم افزارگاهی نرم افزارهایی می نویسیم که وابسته به محیط اجرا هستند. یعنی برنامه نویس روی سیستم خودش، یک سری فایل، تنظیمات و ابزار دارد، توسعه ی نرم افزار و تست آن را روی همین محیط انجام می دهد و همه چیز به درستی کار می کند. بعد از پابلیش، همان نرم افزار، هر جا که مستقر می شود باگ دارد.وقتی مسئول تست، سیستم را تست می کند و باگ پیدا می کند، و یا وقتی مدیر، در مورد یک باگ از برنامه نویس سوال می پرسد، یک جمله ی معروف هست که هیچ کس مایل نیست بشنود: "روی سیستم من درست کار می کند!"این جمله هیچ ارزشی ایجاد نمی کند، چون هیچ کاربری قرار نیست به سیستم برنامه نویس متصل شود و از برنامه استفاده کند. نرم افزار باید ثبات داشته باشد و روی محیط های مختلف، از مرحله ی تست تا عملیاتی شدن به درستی کار کند. برای تحقق این امر، باید محیط توسعه ی مناسب فراهم باشد.طراحی NET (Core). به گونه ای است که به هیچ چیزی در بیرون از خودش وابسته نیست و هر آنچه که نیاز دارد، درون خودش هست. به همین دلیل با containerها کاملا سازگار است، پس روی همان container که کار توسعه را انجام می دهیم، کار تست و عملیات هم قابل انجام است. پس قرار نیست یک خطا را روی محیط عملیاتی ببینیم ولی روی محیط توسعه اثری از آن نباشد، چون همه ی تنظیمات و بستر اجرایی، روی محیط توسعه و عملیات، یکی است.اگر نمی دانید container چیست:container یک واحد است، که همه اجزای یک اپلیکیشن، شامل کد و dependency ها را در خودش بسته بندی می کند. این "بسته بندی"، هر جا که اجرا شود، رفتار یکسانی خواهد داشت. از لپ تاپِ برنامه نویس، تا یک دیتاسنتر اختصاصی، یا cloud.در نتیجه برنامه نویس، فقط به پیاده سازیِ logic نرم افزار و وابستگی هاش فکر خواهد کرد، تیم استقرار هم فقط به deployment می پردازد و دغدغه ای در خصوص جزئیات پیاده سازی، مثل نسخه های مختلف و config ها نخواهد داشت. پابلیش روی یک container داکر:همانطور که در قسمت قبل دیدیم، پابلیش روی Linux، macOS و Windows، به سادگی امکان پذیر است. کافی است محتویات فولدرِ publish را روی سیستم مقصد کپی کنیم.برای داکر هم همان روش به درستی کار می کند، تنها تفاوت اینجاست که باید یک container بسازیم.برای نوشتن برنامه با NET. اولین کاری که کردیم نصب SDK بود.هنگام کار با Docker، کافیست دستور زیر را اجرا کنیم تا image مربوط به dotnet را دریافت کنیم. این image شامل NET SDK. است:docker run -it microsoft/dotnet:latestحالا برای ساختن container:یک فایل text به نام Dockerfile در فولدری که اپلیکیشن آنجا قرار دارد (همانجایی که فایل .csproj هست) بسازید. محتویات این فایل باید به این صورت باشد:FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base COPY bin/Release/net5.0/publish/ /root/ ENTRYPOINT dotnet /root/DotNetConsoleSample.dllدر باکس بالا، دقت کنید که bin/Release/net5.0/publish/ آدرس جایی است که محتویات اپلیکیشن بعد از پابلیش آن جا قرار دارد و DotNetConsoleSample.dll نام dll مربوط به برنامه است.بعد از ساخت و ذخیره ی فایل، دستور زیر را اجرا می کنیم تا container ساخته شود:docker build -t dotnetconsolesample .این دستور از Dockerfile ای که ساختیم استفاده می کند تا container را بسازد. حالا باید در لیست image های Docker، این image را ببینید:dotnetconsolesampleبرای اجرای برنامه در Docker، دستور زیر را اجرا می کنیم:docker run -it dotnetconsolesampleاجرای برنامه با استفاده از docker runپابلیش وب اپلیکیشن روی container:برای پابلیش وب اپلیکیشن روی یک container، باید مقداری تنظیمات انجام دهیم:در فایل Program.cs webBuilder .UseUrls(&quothttp://*:5000/&quot) .UseStartup<Startup>();با استفاده از متد UseUrls، مشخص می کنیم که سرور باید روی چه آدرس و port مشخصی، به request ها پاسخ دهد.فایل Dockerfile به صورت زیر خواهد بود:FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base COPY bin/release/net5.0/publish/ /root/ EXPOSE 5000/tcp ENTRYPOINT dotnet /root/DotNetWebSample.dllدستور Expose، به Docker می گوید که container در هنگام اجرا، باید به کدام port شبکه گوش بدهد.بعد از ذخیره کردن Dockerfile، دستورهای زیر را به ترتیب اجرا می کنیم:dotnet publish -c releasedocker build -t dotnetwebsample .docker run -it -p 5000:5000 dotnetwebsample و روی آدرس http://localhost:5000 می تونیم Hello World را مشاهده کنیم.پکیج کردن پروژهاگر می خواهید اپلیکیشن خود را به صورت یک پکیج در اختیار دیگران قرار دهید یک دستور ساده برای این کار وجود دارد:dotnet pack -c Releaseبعد از اجرای این دستور، یک فایل با نام DotNetConsoleSample.1.0.0.nupkg ساخته می شود. این فایل یک NuGet Packge است و امکان به اشتراک گذاشته شدن کد شما را فراهم می کند.تا اینجا ما با دستورهای زیر کار کردیم:dotnet new consoledotnet new web dotnet restoredotnet builddotnet rundotnet publishdotnet packبه جز این ها، دستورهای دیگری هم توسط CLI قابل اجراست:dotnet clean: Clean build outputs.dotnet msbuild: Provides access to the MSBuild command line.dotnet sln: Options to add, remove, and list projects in a solution file.dotnet test: Runs tests using a test runner.dotnet add reference: Adds a project reference.dotnet add package: Adds a NuGet package.لیست کامل را اینجا ببینید:https://docs.microsoft.com/en-us/dotnet/core/tools/dotnetخلاصه:در این نوشته، یک شروع ساده با NET. را طی مراحل زیر توضیح دادیم:نصب NET SDK.کار با دستورهای ابتدایی NET CLI.ساخت یک console application و یک web applicationپابلیش اپلیکیشن ها و اجرای آن هامنابع:.Net Core in Action | Dustin Metzgardocs.microsoft.com