سرفصلهای دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design
جلسه اول(رایگان)
- معرفی NET 6 و نحوه نصب و استفاده
- بررسی ویژگی های جدید dotNET 6 و تاثیر آنها بر روی پروژه ها
- بررسی ویژگی های جدید سی شارپ 10
- معرفی Program.cs و نحوه کانفیگ ویژگی های مختلف در آن
- بررسی Dependency Injection و سه روش Singleton، Scoped و Transient
- بررسی تاریخچه روش های تولید و عرضه سرویس های از ASMX تا gRPC
جلسه دوم
- بررسی سرعت NET 6 نسبت به نسخه های قدیمی تر
- تبدیل از نسخه های پایین تر به ورژن NET 6 :
- دستورات مربوط به ایجاد و اجرای پروژه ها در محیط VS Code
- فعال سازی ویژگی hot reload در محیط VS Code
- معرفی معماری های پرکاربرد در پیاده سازی پروژه ها
- معرفی و بررسی Clean Code Architecture
- نصب و استفاده از Template Project مربوط به Clean Architecture برای Ardalis
- نصب و استفاده از EF Core
- بررسی عملیات Migration در EF Core
- تفاوت اجرای Async-Await با حالت عادی متدها
جلسه سوم
- معرفی Swagger و مزایای استفاده از آن در Web API ها
- افزودن Annotation به Swagger
- بررسی کانفیگ های مربوط به Swagger در Program.cs
- ادامه محبث EF Core و بررسی روابط بین Entity ها
- استفاده از Data Annotation برای تعریف ویژگی های Property ها
- معرفی و استفاده از روش Fluent API در EF Core
- نصب و استفاده از Auto Mapper
- معرفی CQRS و نحوه جداسازی عملیات براساس ماهیت آنها
- استفاده از Mediator برای پیاده سازی CQRS
- پیاده سازی به صورت CQRS به کمک Mediator
- نحوه افزودن Authentication به Web API
- معرفی Token Authentication و مزایای آن
- استفاده از Refresh Token برای کامل شدن پروسه Authentication در Web API ها
جلسه چهارم
- استفاده از Mediator برای پیاده سازی Use Case ها در حالت CQRS
- نصب MediatR و استفاده از آن
- نوشتن مدل های Request و Response به همراه Handler
- معرفی الگوی Unit of Work و مشکلی که به کمک uof حل می شود
- بررسی روش های رمزنگاری داده ها در ASP.NET Core
جلسه پنجم
- پیاده سازی روش Token Authentication
- افزودن Refresh Token به پروژه برای کامل شدن چرخه Authentication
- نحوه افزودن Authorize Button به Swagger برای Set کردن Token در Swagger
- نحوه دسترسی به Claims در Token های دریافتی در Reuest Header
- بررسی نحوه پیاده سازی دسترسی های کاربر در پروژه ها
جلسه ششم
- بررسی نقشه کلی جداول User-Role-Permission برای مدیریت دسترسی ها
- پیاده سازی جداول در EF Core و نحوه ارتباط جداول با یکدیگر
- افزودن Base Controller برای افزودن Attribute های کلی Controller ها
- کارکردن با File ها و روش های ذخیره و بازیابی فایل ها در ASP.NET Core
- پیاده سازی روش ذخیره و بازیابی فایل ها با فرمت باینری روی دیتابیس
- پیاده سازی روش ذخیره و بازیابی فایل ها روی FTP
جلسه هفتم
- چالش های ذخیره فایل ها روی FTP
- روش نمایش فایل های باینری بر روی مرورگر
- رمزنگاری فایل ها قبل از ذخیره سازی
- Validation روی فایل های دریافتی
- نکات ذخیره فایل روی FTP و به صورت یک فولدر Media در مسیر اجرای پروژه
- خواندن مسیر اجرای پروژه برای ذخیره و بازیابی فایل ها
جلسه هشتم
- بررسی نکات مهم Performance در EF Core
- معرفی و استفاده از ویژگی AsNoTracking در EF Core
- افزودن Paging به کوئری های Linq
- بررسی خطای Circular در EF Core
- روش های Log زدن در ASP.NET Core
- معرفی و استفاده از Serilog
- نحوه حرکت بین Migration های EF Core و Update کردن دیتابیس
- معرفی و استفاده از Mini Profiler در ASP.NET Core
- بررسی Cors Policy در Web API ها
- نحوه افزودن Cors Policy در ASP.NET Core
- معرفی SignalR و کاربرد آن در ASP.NET Core
- مراحل استفاده از SignalR در ASP.NET Core
جلسه نهم
- شروع Domain Driven Design
- بررسی تاریخچه DDD
- معرفی و بررسی اصطلاحات مهم در DDD
- مسئله مطرح شده برای پیاده سازی چیست؟ Domain
- متخصص های کسب و کاری این مسئله چه کسانی هستند ؟ Domain Expert
- نحوه شکست مسئله پیچیده به مسائل کوچکتر : Knowledge Crunching
- مسائل پیچیده Domain یا Problem Space
- راه حل های که برای Problem Space پیدا می کنیم : Solution Space
- نیاز به یک زبان مشترک بین تیم Develop و تیم کسب و کار : Ubiquitous language
- بررسی شکستن Domain به Sub Domain ها
- Core Domain چیست ؟
- Generic Domain و Supporting Domain چیست ؟
- به کمک مفهوم Bounded Context چه کاری انجام می دهیم؟
- نقش Aggregate در DDD چیست ؟
- هر Aggregate می تواند دارای چه بخش هایی باشد؟
جلسه دهم
- نوشتن یک Aggregate با اجزای داخلی
- مروری بر Interface و Abstract Class
- بررسی کلاس Seald
- نحوه Override کردن Operator ها مانند علامت مساوی در کلاس ها
- مقایسه Validation و Invariant ها
- معرفی و بررسی انواع روابط بین کلاس ها مانند Composition و Aggregation و Association
- بررسی بخش Catalog در پیاده سازی یک فروشگاه اینترنتی
- معرفی Event Store و کاربرد آن در DDD
- ایجاد و استفاده از Event Store Context
جلسه یازدهم
- بررسی و پیاده سازی بخش Sub Domain Catalog
- مشخص کردن Use Case هایی این Sub Domain
- معرفی ویژگی Record در سی شارپ و نحوه استفاده از آن
- مقایسه حالت Mutable و Immutable
- معرفی Repository Pattern
- مزایا و معایب Generic Repository
جلسه دوازدهم
- معرفی و کاربرد Domain Event ها
- آیا نیاز داریم Event ها را در جایی ذخیره کنیم ؟
- استفاده از EventStoreDB برای نگهداری سابقه Event ها
- معرفی RabbitMQ و Kafka برای مدیریت بهتر Event ها
- کاربرد Domain Service ها
- نوشتن Domain Service
جلسه سیزدهم
- شروع بخش میکروسرویس، معرفی و تاریخچه میکروسرویس ها
- مقایسه روش Monolithic و Microservice
- چالش های پیش رو در معماری به شکل میکروسرویس
- معرفی ابزارهایی که در معماری میکروسرویس استفاده می شوند
- نحوه جداسازی سازی و شکست یک پروژه به چندین پروژه مستقل در معماری میکروسرویس
- معرفی روش gRPC
- مراحل استفاده از gRPC در پروژه ها
- نصب و استفاده از gRPC
جلسه چهاردهم
- معرفی API Gateway و نقش آن در میکروسرویس ها
- معرفی Ocelot و نحوه استفاده از آن
- بررسی ویژگی ها و امکانات Ocelot
- بررسی ویژگی Routing در Ocelot
- نحوه استفاده از Caching مربوط به Ocelot
- Load Balancer در Ocelot چگونه کار می کند ؟
- Rate Limiting چیست و در Ocelot چطور فعال می شود
- مدیریت Authentication میکروسرویس ها به کمک Ocelot
جلسه پانزدهم
- نحوه کنترل دسترسی ها در Microserice ها
- بررسی انواع روش های ارتباطی بین نرم افزارها (Synchronous و Asynchronous)
- معرفی Message Broker و وظایف آن
- معرفی RabbitMQ و Kafka
- نصب و استفاده از RabbitMQ
- اصطلاحات مهم در RabbitMQ
جلسه شانزدهم
- مثال هایی از عملیاتی که می توان توسط RabbitMQ انجام داد
- بررسی انواع روش های ارسال پیام در RabbitMQ شامل Direct - Fanout - Topic
- کارکردن با پنل مدیریت RabbitMQ برای مشاهده وضعیت صف ها و پیام ها
- کاربرد Exchange در RabbitMQ
- استفاده از Queue و کاربرد آن در RabbitMQ
- نحوه ارسال و دریافت پیام در RabbitMQ
- روش های مانیتورینگ میکروسریس ها
- معرفی و استفاده از Seq برای مانیتورینگ لاگ ها در میکروسرویس ها
- نصب و استفاده از Seq
- معرفی Dokcer و ویژگی های آن
- نصب Docker Desktop روی ویندوز
- نحوه ساخت Docker Image
- کاربرد Docker Hub چیست ؟
- Docker-Compose چه کاری انجام می دهد؟
جلسه هفدهم
- بررسی پنل Seq
- مراحل ایجاد یک Docker Image
- کاربرد فایل Docker-Compose
- معرفی و نقش Kubernetes در دنیای نرم افزار
- معرفی Pod و Node در در Kubernetes
- معرفی CI/CD و مزایای آن
- بررسی چرخه اجرا در CI/CD
- معرفی ابزارها و Library هایی که در پیاده سازی پروژه پایانی نیاز داریم
جلسه هجدهم
- بررسی و بحث های مرتبط با قرارداهای پیاده سازی نرم افزار (چالش ها و مشکلات)
- RFP در قراردادهای نرم افزار چیست ؟
- چگونه Proposal آماده کنیم و در جواب RFP ارسال کنیم؟
- اهمیت استفاده از طرح های اولیه UI به شکل ProtoType و Wireframe
- معرفی نرم افزار Figma برای طراحی صفحات یک پروژه نرم افزاری
- نحوه پیاده سازی طرح های تایید شده در تیم فنی
- هماهنگی با تیم Front برای استاندارد سازی سرویس هایی که می خواهید ارائه دهید
- نحوه مدیریت خطاها چگونه باشد؟
- فرمت خروجی API ها به چه شکلی باشد؟
- استاندارد پیاده سازی Sort و Filter را مشخص می کنیم که در همه API ها از همان مدل استفاده کنیم
- نحوه Authentication و مخصوصا کنترل دسترسی ها به چه شکلی باشد
- معرفی ABP به عنوان یک Framework قدرتمند برای پیاده سازی پروژه ها
جلسه نوزدهم
- شروع پیاده سازی پروژه فروشگاه اینترنتی
- ساخت لایه ها و بخش های مرتبط با Catalog Microservice
- بررسی Strategic Design
- بررسی Tactical Design
- مشخص کردن بخش مدیریت محصولات و ساخت میکروسرویس این بخش
- معرفی و استفاده از Mini API
جلسه بیستم
- افزودن Media به پروژه Catalog
- معرفی الگوی Specification
- استفاده از Ardalis.Specification برای پیاده سازی الگوی Specification
- افزودن Generic Repository به پروژه
- بررسی چرخه کامل ذخیره و بازیابی فایل ها
- اضافه کردن Fluent Validation برای افزودن Validation به Request Model ها
- معرفی Mapster برای بحث Mapping و مقایسه آن با Auto Mapper
- معرفی ابزار MassTransit
- معرفی Dapr و نقش مهم آن در مدیریت میکروسرویس ها
- بررسی ساختار و سرویس های Dapr
جلسه بیست و یکم
- نحوه نصب و استفاده از Dapr
- اجرای داشبورد مربوط به Dapr برای مشاهده وضعیت میکروسرویس ها
- افزودن Dapr به ASP.NET Core
- نحوه اجرای پروژه به کمک Dapr
- بررسی پروژه Catalog و نحوه تعامل به کمک Dapr
جلسه بیست و دوم
- بررسی یک پروژه کامل پیاده سازی شده به کمک Dapr
- بررسی سرویس های درگیر در روند پروژه
- نحوه تعامل سرویس ها با یکدیگر براساس امکانات Dapr
- بررسی ویژگی Service Invocation در Dapr
- کاربرد State Management در Dapr
- چگونه Publish Subscribe را به کمک Dapr انجام دهیم
- Output Binding چه کاربردی دارد؟
- Input Binding در Dapr چه موقع استفاده می شود
- مدیریت رمزها به کمک Secret Managment در Dapr
- نقش Actors در Dapr
جلسه بیست و سوم
پیاده سازی پروژه پایانی : فروشگاه اینترنتی
نوشتن FileServer : نحوه فراخوانی از طریق gRPC یا http به کمک Dapr
- آپلود فایل تکی :
- appName
- entity
- userId
- File
- byte[]
- type
- extension
- fileName
- آپلود فایل گروهی
- دانلود فایل
*** تا جلسه بیست و دوم پروژه ها روی ورژن dot net 6 بود. از این جلسه پروژه های جدید روی dot net 7 ایجاد خواهد شد.
نیازمندی های نرم افزاری برای dot net 7 :
- نصب dot net SDK 7
- آپدیت کردن Visual Studio 2022 به ورژن 17.4
جلسه بیست و چهارم
جلسه بیست و چهارم :
(جلسه دوم پیاده سازی پروژه پایانی)
نحوه ارتباط بین سرویس Catalog و FileServer : ارتباط از طریق فراخوانی سرویس یا Service Invocation
ما می توانیم به دو صورت فراخوانی مستقیم و فراخوانی به کمک Dapr این کار را انجام دهیم :
- استفاده از HttpClient
- استفاده از HttpClient ولی به کمک Dapr
مراحل افزودن Dapr به پروژه FileServer :
- نصب AspNetCore از nuget
- افزودن سرویس Dapr در cs به شکل زیر :
var daprHttpPort = Environment.GetEnvironmentVariable("DAPR_HTTP_PORT") ?? "3602";
var daprGrpcPort = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT") ?? "60002";
builder.Services.AddDaprClient(builder => builder
.UseHttpEndpoint($"http://localhost:{daprHttpPort}")
.UseGrpcEndpoint($"http://localhost:{daprGrpcPort}"));
builder.Services.AddControllers().AddDapr();
- تغییر دستور Run() به دستور app.Run("http://localhost:6002");
- افزودن فایل ps1 برای اجرای dapr و اجرای خود پروژه :
dapr run `
--app-id fileserverervice `
--app-port 6002 `
--dapr-http-port 3602 `
--dapr-grpc-port 60002 `
--config ../../dapr/config/config.yaml `
--components-path ../../dapr/components `
dotnet run
- اجرا دو دستور بالا در محیط powerShell در فولدر مربوط به روت پروژه
مراحل افزودن Dapr به پروژه Catalog :
- نصب AspNetCore از nuget
- افزودن سرویس Dapr در cs به شکل زیر :
var daprHttpPort = Environment.GetEnvironmentVariable("DAPR_HTTP_PORT") ?? "3601";
var daprGrpcPort = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT") ?? "60001";
builder.Services.AddDaprClient(builder => builder
.UseHttpEndpoint($"http://localhost:{daprHttpPort}")
.UseGrpcEndpoint($"http://localhost:{daprGrpcPort}"));
builder.Services.AddControllers().AddDapr();
- تغییر دستور Run() به دستور app.Run("http://localhost:6001");
- افزودن سرویس LocalFileStorageService در فایل cs به صورت زیر برای اینکه httpClient مورد نیاز این سرویس از طریق dapr تامین شود.
builder.Services.AddTransient<IFileStorageService>(_ =>
new LocalFileStorageService(DaprClient.CreateInvokeHttpClient(
"fileserverervice", $"http://localhost:{daprHttpPort}")));
افزودن سرویس Identity به پروژه ها :
- نوشتن یک Identity Service مستقل که باید بتواند نیازهای زیر را پاسخگو باشد :
- امکان Register کردن
- امکان Authenticate
- امکان تولید توکن جدید از روی RefreshToken
- امکان Forgot Password
- مدیریت نقش ها و دسترسی های کاربران
- در سرویس Catalog یا FileServer ، باید در تمام Request ها Token به سمت این دو سرویس یا سرویس های دیگر ارسال شود و valid بودن Token سنجیده و سپس پاسخ داده شود.
جلسه بیست و پنجم
جلسه بیست و پنجم :
(جلسه سوم پیاده سازی پروژه پایانی)
نحوه مدیریت دسترسی ها :
کنترل دسترسی ها در سطح Action ها :
کاربر derambakht یا نقش Operator دسترسی های زیر را دارد :
- Catalog :
- افزودن گروه بندی محصول جدید ()
- مشاهده لیست گروه بندی محصولات
- FileServer :
- امکان آپلود فایل جدید
فرمت تعریف کلید برای دسترسی ها : {appid}-{entity}-{action}
فرمت تعریف کلید برای دسترسی ها : {entity}-{action}
مثل : category-add - در جدول permission در میکروسرویس Identity : title, key,
نحوه ارتباط Catalog با Identity :
نحوه نصب و استفاده از Redis به صورت مستقیم در پروژه ها :
- نصب Redis روی سیستم عامل یا به کمک نصب روی Docker
- افزودن Package مربوط به Redis بر روی پروژه مورد نظر
- افزودن سرویس Redis در cs پروژه مورد نظر
- Inject کردن کلاس مربوط به نوشتن و خواندن از Cache در Controller یا Service مورد نظر
1 - نصب Redis بر روی Docker :
- دریافت image مربوط به Redis از روی Docker Hub با دستور زیر :
docker pull redis
- اجرای Image برای ساختن Container مربوط به Redis بر روی Docker
docker run -d -h redis -v redis-data:/data -p 6379:6379 --name redis --restart always redis:latest /bin/sh -c redis-server --appendonly yes --requirepass "redis"
2- افزودن Package مربوط به Redis بر روی پروژه مورد نظر
Install-Package Microsoft.Extensions.Caching.StackExchangeRedis
3- افزودن سرویس Redis در Program.cs پروژه مورد نظر
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379,password=redis";
options.InstanceName = "identitystore";
});
4- Inject کردن کلاس مربوط به نوشتن و خواندن از Cache در Controller یا Service مورد نظر
private readonly IDistributedCache _cache;
[HttpGet("Test")]
public async Task<IActionResult> Test()
{
var options = new DistributedCacheEntryOptions();
options.SetSlidingExpiration(TimeSpan.FromMinutes(1));
options.SetAbsoluteExpiration(TimeSpan.FromMinutes(10));
await _cache.SetStringAsync("ali", "123456", options);
return Ok();
}
[HttpGet("Test2")]
public async Task<string> Test2()
{
var value = await _cache.GetStringAsync("ali");
return value;
}
نحوه استفاده از ویژگی State-Management (Cache) مربوط به Dapr در پروژه ها :
- در ابتدا باید فایل dapr run برای پروژه مورد نظر نوشته شود :
dapr run `
--app-id identityservice `
--app-port 6005 `
--dapr-http-port 3605 `
--dapr-grpc-port 60005 `
--config ../../dapr/config/config.yaml `
--components-path ../../dapr/components `
- در محلی که نیاز داریم مقداری را در state به کمک dapr ذخیره کنیم کلاس DaprClient را inject می کنیم :
private readonly DaprClient _daprClient;
- سپس برای نوشتن مقدار در state از دستور زیر استفاده می کنیم :
await _daprClient.SaveStateAsync<List<string>>(DAPR_STORE_NAME,stateKey, item.PermissioKeys);
- در ادامه برای خواندن مقدار state در همان Application یا Application دیگر از دستور زیر استفاده می کنیم :
var appPermissions= await _daprClient.GetStateAsync<List<string>>(DAPR_STORE_NAME, stateKey.ToLower());
*** حتما باید کانفیگ های زیر را در فایل های مربوط به کانفیگ dapr انجام دهیم :
فایل اول : statestore.yaml : در داخل این فایل مشخص می کنیم که برای state از کدام بستر مثلا Redis با چه ویژگی هایی و چه application های مجاز.
فایل دوم : secrets-file.yaml : مشخص می کنیم که ویژگی های امنیتی مانند password از کدام json فایل خوانده شود که در این مثال همان فایل secrets.json می باشد.
فایل سوم : secrets.json : همه کدهای امنیتی مانند رمزهای عبور Redis یا هر ابزار دیگری مثل SMTP Mail Server را نگهداری می کنیم.
*** در این فایل ها باید توجه زیادی به یکی بودن namespace ها و همچنین بخش scopes که مشخص می کند کدام میکروسرویس ها اجازه استفاده دارند را داشته باشیم.
پایان جلسه بیست و پنجم