دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design

25 رای ثبت شده
video player
دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design

دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design

دوره آموزش کاربردی و ترکیبی ASP.NET Core Web API به همراه پیاده سازی براساس Domain Driven Design و طراحی برپایه معماری Microservice که باعث می شود شما در یک دوره و به صورت پروژه محور تسلط بسیار خوبی روی این مباحث مهم، کاربردی و پیچیده داشته باشید.

25 رای ثبت شده
مدرس: محسن درم بخت (دارای گروه اختصاصی، برای پشتیبانی و پرسش و پاسخ)
video player
دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design
1,200,000 تومان 2,000,000 تومان
  • مدت زمان دوره: 62:48:29
  • امکان دانلود کل دوره به صورت یکجا
  • ویدیوهای آموزشی با کیفیت
  • دسترسی همیشگی به دوره خریداری شده
  • امکان درج پرسش و پاسخ
1,200,000 تومان 2,000,000 تومان
  • دسترسی به فایل ها و محتوای متنی ضمیمه شده
  • ویدیو های آموزشی با کیفیت
  • امکان اجرا در موبایل و تبلت
  • دسترسی همیشگی به ویدیو خریداری شده
  • امکان درج پرسش و پاسخ

آنچه در دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design می‌آموزید:

  • به صورت حرفه ای پروژه های Web API را پیاده سازی کنید
  • روی Domain Driven Design تسلط داشته باشید
  • بتوانید صفر تا صد یک پروژه backend را پیاده سازی کنید
  • معماری Microservice را کامل بشناسید و بتوانید چالش های Microservice را در پیاده سازی پروژه ها حل کنید
  • Docker را بشناسید و به پروژه خود Dockerfile را افزوده و در نهایت Docker Image تولید کنید
  • با نقش Kubernetes آشنا شوید و بتوانید میکروسرویس های خودتان را روی Kubernetes اجرا کنید
  • با gRPC کار کنید و بتوانید ارتباط بین Application ها خود را با gRPC برقرار کنید
  • RabbitMQ را نصب و از آن برای تبادل و مدیریت پیام ها استفاده کنید
  • بدانید API Gateway چیست و Ocelot چگونه کار می کند
بیشتر ...
پیش نیازها:
  • تسلط به سی شارپ
  • آشنایی با دستورات SQL
  • داشتن زمان تمرین و مرور مطالب

سرفصل‌های دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design

زمان برگزار شده: 62:48:00 تعداد دروس: 26

62:48:29 26 بخش
03:00:32
جلسه اول(رایگان)
  • معرفی NET 6 و نحوه نصب و استفاده
  • بررسی ویژگی های جدید dotNET 6 و تاثیر آنها بر روی پروژه ها
  • بررسی ویژگی های جدید سی شارپ 10
  • معرفی Program.cs و نحوه کانفیگ ویژگی های مختلف در آن
  • بررسی Dependency Injection و سه روش Singleton، Scoped و Transient
  • بررسی تاریخچه روش های تولید و عرضه سرویس های از ASMX تا gRPC
02:54:21
جلسه دوم
  • بررسی سرعت 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 با حالت عادی متدها
02:49:29
جلسه سوم
  • معرفی 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 ها
02:49:11
جلسه چهارم
  • استفاده از Mediator برای پیاده سازی Use Case ها در حالت CQRS
  • نصب MediatR و استفاده از آن
  • نوشتن مدل های Request و Response به همراه Handler
  • معرفی الگوی Unit of Work و مشکلی که به کمک uof حل می شود
  • بررسی روش های رمزنگاری داده ها در ASP.NET Core
02:51:21
جلسه پنجم
  • پیاده سازی روش Token Authentication
  • افزودن Refresh Token به پروژه برای کامل شدن چرخه Authentication
  • نحوه افزودن Authorize Button به Swagger برای Set کردن Token در Swagger
  • نحوه دسترسی به Claims در Token های دریافتی در Reuest Header
  • بررسی نحوه پیاده سازی دسترسی های کاربر در پروژه ها
02:48:7
جلسه ششم
  • بررسی نقشه کلی جداول User-Role-Permission برای مدیریت دسترسی ها
  • پیاده سازی جداول در EF Core و نحوه ارتباط جداول با یکدیگر
  • افزودن Base Controller برای افزودن Attribute های کلی Controller ها
  • کارکردن با File ها و روش های ذخیره و بازیابی فایل ها در ASP.NET Core
  • پیاده سازی روش ذخیره و بازیابی فایل ها با فرمت باینری روی دیتابیس
  • پیاده سازی روش ذخیره و بازیابی فایل ها روی FTP
02:48:12
جلسه هفتم
  • چالش های ذخیره فایل ها روی FTP
  • روش نمایش فایل های باینری بر روی مرورگر
  • رمزنگاری فایل ها قبل از ذخیره سازی
  • Validation روی فایل های دریافتی
  • نکات ذخیره فایل روی FTP و به صورت یک فولدر Media در مسیر اجرای پروژه
  • خواندن مسیر اجرای پروژه برای ذخیره و بازیابی فایل ها
02:53:26
جلسه هشتم
  • بررسی نکات مهم 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
02:36:59
جلسه نهم
  • شروع 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 می تواند دارای چه بخش هایی باشد؟
02:49:18
جلسه دهم
  • نوشتن یک Aggregate با اجزای داخلی
  • مروری بر Interface و Abstract Class 
  • بررسی کلاس Seald
  • نحوه Override کردن Operator ها مانند علامت مساوی در کلاس ها
  • مقایسه Validation و Invariant ها 
  • معرفی و بررسی انواع روابط بین کلاس ها مانند Composition و Aggregation و Association
  • بررسی بخش Catalog در پیاده سازی یک فروشگاه اینترنتی
  • معرفی Event Store و کاربرد آن در DDD
  • ایجاد و استفاده از Event Store Context
02:39:45
جلسه یازدهم
  • بررسی و پیاده سازی بخش Sub Domain Catalog
  • مشخص کردن Use Case هایی این Sub Domain
  • معرفی ویژگی Record در سی شارپ و نحوه استفاده از آن
  • مقایسه حالت Mutable و Immutable
  • معرفی Repository Pattern
  • مزایا و معایب Generic Repository
02:36:56
جلسه دوازدهم
  • معرفی و کاربرد Domain Event ها
  • آیا نیاز داریم Event ها را در جایی ذخیره کنیم ؟
  • استفاده از EventStoreDB برای نگهداری سابقه Event ها
  • معرفی RabbitMQ و Kafka برای مدیریت بهتر Event ها
  • کاربرد Domain Service ها
  • نوشتن Domain Service
02:37:21
جلسه سیزدهم
  • شروع بخش میکروسرویس، معرفی و تاریخچه میکروسرویس ها
  • مقایسه روش Monolithic و Microservice
  • چالش های پیش رو در معماری به شکل میکروسرویس
  • معرفی ابزارهایی که در معماری میکروسرویس استفاده می شوند
  • نحوه جداسازی سازی و شکست یک پروژه به چندین پروژه مستقل در معماری میکروسرویس
  • معرفی روش gRPC
  • مراحل استفاده از gRPC در پروژه ها
  • نصب و استفاده از gRPC
02:37:56
جلسه چهاردهم
  • معرفی API Gateway  و نقش آن در میکروسرویس ها
  • معرفی Ocelot و نحوه استفاده از آن
  • بررسی ویژگی ها و امکانات Ocelot
  • بررسی ویژگی Routing در Ocelot
  • نحوه استفاده از Caching مربوط به Ocelot
  • Load Balancer در Ocelot چگونه کار می کند ؟
  • Rate Limiting چیست و در Ocelot چطور فعال می شود
  • مدیریت Authentication میکروسرویس ها به کمک Ocelot
02:35:52
جلسه پانزدهم
  • نحوه کنترل دسترسی ها در Microserice ها
  • بررسی انواع روش های ارتباطی بین نرم افزارها (Synchronous و Asynchronous)
  • معرفی Message Broker و وظایف آن
  • معرفی RabbitMQ و Kafka
  • نصب و استفاده از RabbitMQ
  • اصطلاحات مهم در RabbitMQ
02:44:7
جلسه شانزدهم
  • مثال هایی از عملیاتی که می توان توسط RabbitMQ انجام داد
  • بررسی انواع روش های ارسال پیام در RabbitMQ شامل Direct - Fanout - Topic
  • کارکردن با پنل مدیریت RabbitMQ برای مشاهده وضعیت صف ها و پیام ها
  • کاربرد Exchange در RabbitMQ
  • استفاده از Queue و کاربرد آن در RabbitMQ
  • نحوه ارسال و دریافت پیام در RabbitMQ
  • روش های مانیتورینگ میکروسریس ها
  • معرفی و استفاده از Seq برای مانیتورینگ لاگ ها در میکروسرویس ها
  • نصب و استفاده از Seq
  • معرفی Dokcer و ویژگی های آن
  • نصب Docker Desktop روی ویندوز
  • نحوه ساخت Docker Image
  • کاربرد Docker Hub چیست ؟
  • Docker-Compose چه کاری انجام می دهد؟
01:51:0
جلسه هفدهم
  • بررسی پنل Seq
  • مراحل ایجاد یک Docker Image 
  • کاربرد فایل Docker-Compose
  • معرفی و نقش Kubernetes در دنیای نرم افزار
  • معرفی Pod و Node در در Kubernetes
  • معرفی CI/CD و مزایای آن
  • بررسی چرخه اجرا در CI/CD
  • معرفی ابزارها و Library هایی که در پیاده سازی پروژه پایانی نیاز داریم
01:54:19
جلسه هجدهم
  • بررسی و بحث های مرتبط با قرارداهای پیاده سازی نرم افزار (چالش ها و مشکلات)
  • RFP در قراردادهای نرم افزار چیست ؟
  • چگونه Proposal آماده کنیم و در جواب RFP ارسال کنیم؟
  • اهمیت استفاده از طرح های اولیه UI به شکل ProtoType و Wireframe
  • معرفی نرم افزار Figma برای طراحی صفحات یک پروژه نرم افزاری
  • نحوه پیاده سازی طرح های تایید شده در تیم فنی
  • هماهنگی با تیم Front برای استاندارد سازی سرویس هایی که می خواهید ارائه دهید
  • نحوه مدیریت خطاها چگونه باشد؟
  • فرمت خروجی API ها به چه شکلی باشد؟
  • استاندارد پیاده سازی Sort و Filter را مشخص می کنیم که در همه API ها از همان مدل استفاده کنیم
  • نحوه Authentication و مخصوصا کنترل دسترسی ها به چه شکلی باشد
  • معرفی ABP به عنوان یک Framework قدرتمند برای پیاده سازی پروژه ها
02:04:54
جلسه نوزدهم
  • شروع پیاده سازی پروژه فروشگاه اینترنتی
  • ساخت لایه ها و بخش های مرتبط با Catalog Microservice
  • بررسی Strategic Design
  • بررسی Tactical Design
  • مشخص کردن بخش مدیریت محصولات و ساخت میکروسرویس این بخش
  • معرفی و استفاده از Mini API
02:02:19
جلسه بیستم
  • افزودن Media به پروژه Catalog
  • معرفی الگوی Specification
  • استفاده از Ardalis.Specification برای پیاده سازی الگوی Specification
  • افزودن Generic Repository به پروژه
  • بررسی چرخه کامل ذخیره و بازیابی فایل ها
  • اضافه کردن Fluent Validation برای افزودن Validation به Request Model ها
  • معرفی Mapster برای بحث Mapping و مقایسه آن با Auto Mapper
  • معرفی ابزار MassTransit
  • معرفی Dapr و نقش مهم آن در مدیریت میکروسرویس ها
  • بررسی ساختار و سرویس های Dapr
01:59:43
جلسه بیست و یکم
  • نحوه نصب و استفاده از Dapr
  • اجرای داشبورد مربوط به Dapr برای مشاهده وضعیت میکروسرویس ها
  • افزودن Dapr به ASP.NET Core
  • نحوه اجرای پروژه به کمک Dapr
  • بررسی پروژه Catalog و نحوه تعامل به کمک Dapr
01:43:15
جلسه بیست و دوم
  • بررسی یک پروژه کامل پیاده سازی شده به کمک Dapr
  • بررسی سرویس های درگیر در روند پروژه
  • نحوه تعامل سرویس ها با یکدیگر براساس امکانات Dapr
  • بررسی ویژگی Service Invocation در Dapr
  • کاربرد State Management در Dapr
  • چگونه Publish Subscribe را به کمک Dapr انجام دهیم
  • Output Binding چه کاربردی دارد؟
  • Input Binding در Dapr چه موقع استفاده می شود
  • مدیریت رمزها به کمک Secret Managment در Dapr
  • نقش Actors در Dapr
01:54:15
جلسه بیست و سوم

پیاده سازی پروژه پایانی : فروشگاه اینترنتی

 

نوشتن 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
02:15:15
جلسه بیست و چهارم

جلسه بیست و چهارم :

(جلسه دوم پیاده سازی پروژه پایانی)

نحوه ارتباط بین سرویس 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 سنجیده و سپس پاسخ داده شود.
01:46:6
جلسه بیست و پنجم

جلسه بیست و پنجم :

(جلسه سوم پیاده سازی پروژه پایانی)

نحوه مدیریت دسترسی ها :

کنترل دسترسی ها در سطح 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 که مشخص می کند کدام میکروسرویس ها اجازه استفاده دارند را داشته باشیم.

پایان جلسه بیست و پنجم

01:04:30
جلسه بیست و ششم

جلسه بیست و ششم :

نحوه نوشتن و مدیریت Log در میکروسرویس ها :

مراحل تهیه و استفاده از Log ها :

- تولید لاگ مناسب و کاربری

- جمع آوری لاگ در یک سرور

- یکسان سازی و هم شکل کردن لاگ های تولیدی توسط App های مختلف

- کوئری زدن رولاگ ها و ساخت داشبوردهای لاگ برای استفاده نگهداری از سیستم ها و همینطور استفاده تیم Business

انواع لاگ قابل استفاده :

- لاگ هایی که توسط Application ها تولید می شوند.

- لاگی که میزان استفاده و وضعیت Application ما را نشان می دهد.(به کمک Metrics در ASP.NET)

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

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

 

راه حل جامع برای مدیریت Log ها : استفاده از ELK، یکی از بهترین راه حل های برای مدیریت Log در سیستم های نرم افزاری باشد.

ELK Stack : راه حلی جامع از شرکت Elasticsearch co برای مدیریت لاگ ها.

- Log Beats : وظیفه جمع آوری لاگ از کانال های مختلف را دارد. برای لاگ های مختلف ما Beat های مرتبط داریم. مثلا FileBeat وظیفه جمع آوری لاگ ها به صورت فایل را دارد.

- Logstash : لاگ های جمع آوری را شده را یکسان سازی (هم شکل سازی) می کند و در داخل دیتابیس Elasticsearch قرار می دهد.

-Elasticseach : دیتابیس No-SQL است که لاگ های جمع آوری شده و یکسان سازی شده را در آن قرار می دهیم.

- Kibana : ابزاری برای داشبوردسازی روی داده هایی که در داخل Elasticsearch قرار گرفته است.

مشکل جستجو در داده های توسط کاربر : کاربر یک درخواست یا جستجویی انجام می دهد که در پشت صحنه ما باید روی بیش از یک دیتابیس جستجو انجام دهیم(به خاطر اینکه به ازای هر میکروسرویس، یک دیتابیس جداگانه طراحی کرده ایم.)

راه حل درست : داده های مرتبط با هم که در جستجوی کاربران و از دید کاربر به صورت یک entity واحد به همراه وابستگی ها است، باید در زمان ذخیره این داده به صورت index شده در دیتابیس Elasticsearch هم ذخیره شود و سپس کوئری های جستجوی ما روی این دیتابیس اجرا شود.

خسته نباشید.

جلسه آینده پیاده سازی جستجوی پیشرفته به کمک Elasticsearch

با دوره آموزش میکروسرویس به همراه آموزش Domain Driven Design بیشتر آشنا شوید:

کامل ترین دوره آموزش میکروسرویس به زبان فارسی که به صورت کاملا پروژه محور و کاربردی آموزش داده شده است. در آموزش Microservice، آموزش Domain Driven Design هم گفته شده است و ساختار پروژه به صورت دامین دریون دیزاین پیاده سازی شده است. استفاده از روش ها و کتابخانه های معروف و پرکاربرد مانند CQRS - gRPC - API Gateway و تعداد زیادی که در ادامه مطلب به صورت تفکیک شده در هر جلسه گفته شده است، آموزش داده شده است.

این دوره دید بسیار کاملی به شما درباره میکروسرویس ها و معماری پروژه ها با این ساختار به شما خواهد داد. هر کدام از روش ها و کتابخانه های استفاده شده در دوره آموزش کاربردی میکروسرویس می تواند به صورت جداگانه ای برای شما مسیر یادگیری ایجاد کند و پس از پایان دوره، به سراغ یادگیری آن مطالب به صورت عمیق تر بروید. هدف این دوره انتقال یک تصویر کلی به شما درباره معماری میکروسرویس و تفاوت های آن با روش های دیگر است که باعث افزایش توانایی شما در کار با پروژه های بزرگ و شناخت معماری هایی مثل میکروسرویس باشد.

در دوره کاربردی و پروژه محور آموزش میکروسرویس به همراه آموزش Domain Driven Design شما می توانید با یادگیری و تمرین مطالب گفته شده، تسلط خوبی در زمینه Domain Driven Design و Microservic بدست بیاورید و بتوانید در پایان دوره، صفر تا صد یک پروژه را با معماری میکروسرویس و Domain Driven طراحی، پیاده سازی و در نهایت بر روی Docker و Kubernetes اجرا کنید. سرفصل های دوره مرتبط با پروژه های نرم افزاری و چالش های واقعی تیم های نرم افزاری آماده شده است، که به شما کمک می کند بعد از گذراندن این دوره دید بهتر و تسلط بیشتری روی معماری پروژه ها و همچنین شناخت و استفاده از ابزارهای مرتبط داشته باشید.

مدت زمان دوره 62 ساعت می باشد که در ادامه به مرور سرفصل و مطالب گفته شده پرداخته ایم. برای مقایسه دوره با دوره های مشابه می توانید به مطالب گفته شده در کلاس که در ادامه به صورت مختصر آورده شده، دقت بفرمایید. در این دوره در ابتدا به نکات نوشتن Web API ها در ASP.NET Core پرداخته ایم. سپس الگوهایی معروف و پرکاربرد مثل CQRS را استفاده کرده ایم. در بخش دوم سراغ Domain Driven Design رفته ایم و با این برنامه خود را توسعه داده ایم. در بخش سوم پروژه خود را در معماری Microservice توسعه داده ایم و در بخش چهارم نحوه اجرا روی Kubernetes را انجام داده ایم. این چهار بخش اصلی بوده که در کنار هم مطالب و ابزارهای مختلفی هم معرفی و استفاده شده است.

سرفصل دوره به تفکیک هر جلسه :

جلسه اول :

  • معرفی 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

 

جلسه بیست و سوم (جلسه اول پیاده سازی پروژه پایانی) :

  • توضیح ساختار کلی پروژه پایانی
  • ساخت سرویس Catalog
  • ساخت سرویس FileServer
  • ارتبط بین Catalog و FileServer به کمک Dapr

 

جلسه بیست و چهارم  (جلسه دوم پیاده سازی پروژه پایانی) :

  • تکمیل سرویس FileServer
  • ساخت سرویس Identity
  • اعمال Authentication بر روی سرویس های Catalog

جلسه بیست و پنجم : 

  • نحوه مدیریت دسترسی ها
  • مشحص کردن مدل ارتباط بین Identity و Catalog
  • معرفی Redis و نصب و راه اندازی آن
  • نحوه راه اندازی Redis روی Docker
  • افزودن Redis به پروژه و استفاده مستقیم از آن
  • استفاده از State Manament به کمک Dapr
  • ذخیره دسترسی های کاربر به کمک Dapr در Identity
  • نحوه چک کردن دسترسی کاربر در Catalog از طریق خواندن Dapr State ها

جلسه بیست و ششم : 

  • مراحل تهیه و استفاده از Log ها
  • انواع لاگ قابل استفاده
  • راه حل جامع برای مدیریت Log ها
  • بررسی ELK Stack
  • معرفی Beats
  • کاربرد Logstash
  • استفاده از Elasticsearch
  • کاربرد Kibana
  • مشکل جستجو در داده های توسط کاربر

جلسه بیست و هفتم : برگزار نشده

 

*** همه فایل های جلسات شامل جزوه، فایل های پروژه ها و ویدئوها، همگی از طریق سایت در دسترس می باشد و با خرید دوره می توانید براحتی آنها را دانلود کرده و مشاهده بفرمایید.

*** دوره دارای یک گروه پشتیبانی می باشد که می توانید سوال های فنی خود را از استاد دوره بپرسید.

*** مطالب جدید مانند معرفی و استفاده از NET 7 هم به صورت بخش های تکمیلی ضبط می شود و به دوره افزوده می شود.

محسن درم بخت

استاد دوره: محسن درم بخت

مدیر پروژه، مشاور و مدرس برنامه نویسی
26 دوره
آقای مهندس محسن درم بخت مدیرعامل شرکت سپید آریا، مشاور و مدرس در حوزه تولید نرم افزار می باشند. تجربه ایشان در زمینه تولید نرم افزارهای سازمانی می باشد و از سال 1387 مشغول به فعالیت در حوزه تولید نرم افزار می باشند. مطالب و سرفصل های آموزشی ارائه شده توسط ایشان، همگی منطبق بر نیاز بازار کار و مورد استفاده در پروژه های نرم افزاری می باشد. تجربه پیاده سازی نرم افزارهای متفاوت و همچنین مشاوره در سازمان ها و شرکت های بزرگ باعث شده، تسلط و دانش ایشان در زمینه تولید و توسعه نرم افزارها برای دانشجویان بسیار مفید و کاربردی باشد.
نظرات
arian haghani 1402/05/24

مرسی از دوره خوبتون جناب درم بخت بابت این دوره ،من به شخصه خیلی منتظر دوره rabbitmq و grpc هستم ...

arian haghani 1402/05/24
armin ghafari 1402/05/13

armin ghafari 1402/05/13
لیلا غزلباش 1402/05/06

با تشکر از آموزشهای ارزشمندتان در فهم راحتتر مطالب پیچیده.

لیلا غزلباش 1402/05/06
نرگس السادات خضوعی 1402/04/30

من این دوره رو دیروز خریداری کردم و فعلا فقط جلسه اول آن را مشاهده کردم ولی به نظرم نوع آموزش و تسلط مدرس بسیار عالی است و یکی از ویژگی های خوب تدریس ایشان که دوست داشتم این هست که همون اول مسیر اصلی راه رو براتون ترسیم می کند و شما رو غرق در اطلاعات می کند و بعد به تفصیل مطالب رو شرح می دهد.

نرگس السادات خضوعی 1402/04/30
محمد حسن پاک نژاد 1402/01/16

سلام و خسته نباشید جانانه بر استاد بزرگوار آقای محسن درم بخت ، دوره به شدت عالی بود ، اینجانب از تدریس دوره میکروسرویس جنابعالی بهره کافی را برده و تشکر خود را بابت این دوره جامع پذیرا باشید ، التماس دعا

محمد حسن پاک نژاد 1402/01/16
حسین فولادوندی 1401/12/26

حسین فولادوندی 1401/12/26
محمدرضا عسگری 1401/12/24

محمدرضا عسگری 1401/12/24
ن خ 1401/10/25

عالی. از استاد محترم ممنونم.

ن خ 1401/10/25
محمد ورپشتی 1401/10/23

من الان جلسه 5 هستم و تا اینجا واقعا خوب و حرفه ای بوده.من خودم خیلی سالی هست که حرفه ای کد میزنم ولی با این حال این دوره خیلی خوب و مفید هست هر جلسه کلی نکته جدید داشت

محمد ورپشتی 1401/10/23
کامیاب رستمی 1401/09/17

کامیاب رستمی 1401/09/17
مهرداد حضرتی 1401/09/09

مهرداد حضرتی 1401/09/09
احسان سیدزاده 1401/09/03

بسیار عالی

احسان سیدزاده 1401/09/03
بهناز قاسمی 1401/08/25

- بهترین استاد - بسیار کابردی - شامل تمام نکات مهم پیاده سازی -عالیترین دوره ی ک خریداری کردم ممنون از شما آقای درمبخت

بهناز قاسمی 1401/08/25
مژده سلفی 1401/08/09

مژده سلفی 1401/08/09
moh moh 1401/07/07

moh moh 1401/07/07
mohammad shayestehfar 1401/06/19

mohammad shayestehfar 1401/06/19
zeinab rahimi 1401/06/11

عالی از بهترین دوره هایی که شرکت کردم

zeinab rahimi 1401/06/11
مهرزاد تجاره 1401/05/18

مهرزاد تجاره 1401/05/18
سمانه عبدی 1401/05/03

دوره کامل و کاربردی با تدریس عالی استاد درم بخت

سمانه عبدی 1401/05/03
محمد جواد جهان بین 1401/05/02

محمد جواد جهان بین 1401/05/02
محمد اعظمی 1401/04/15

عالی مثل همیشه فقط عالی تر میشه اگه فایل جلسات رو هم قرار بدید تا به کدها دسترسی داشته باشیم بتونیم یه مروری روی کدها داشته باشیم مچکرم از زحماتتون

محمد اعظمی 1401/04/15
مریم هاشمی 1401/03/30

مریم هاشمی 1401/03/30
بهرام بزرگمهر 1401/03/03

یک دوره فوق العاده کاربردی از یک مدرس حرفه ای

بهرام بزرگمهر 1401/03/03