اضافه کردن ایترفیس و کلاس ارث بری در program
افزودن سرویسها به کانتینر DI (Dependency Injection)
csharp
builder.Services.AddScoped<IDataBaseContext, DataBaseContext>();
builder.Services.AddScoped<IGetUsersService, GetUsersService>();
builder.Services.AddScoped<IGetRolesService, GetRolesService>();
AddScoped<IDataBaseContext, DataBaseContext>();
تعریف: این خط به DI Container میگوید که هر بار که نیاز به IDataBaseContext وجود دارد، یک نمونه از DataBaseContext ایجاد کند.
و Scope: Scoped به این معنی است که یک نمونه جدید برای هر درخواست HTTP ساخته میشود و تا پایان آن درخواست استفاده میشود.
AddScoped<IGetUsersService, GetUsersService>();
تعریف: این خط به DI Container میگوید که هر بار که نیاز به IGetUsersService وجود دارد، یک نمونه از GetUsersService ایجاد کند.
و Scope: همانند IDataBaseContext، Scoped به این معنی است که یک نمونه جدید برای هر درخواست HTTP ساخته میشود.
AddScoped<IGetRolesService, GetRolesService>();
تعریف: این خط به DI Container میگوید که هر بار که نیاز به IGetRolesService وجود دارد، یک نمونه از GetRolesService ایجاد کند.
و Scope: باز هم، Scoped به این معنی است که یک نمونه جدید برای هر درخواست HTTP ساخته میشود.
نتیجهگیری
این خطوط کد سه سرویس مختلف را به DI Container اضافه میکنند و به برنامه شما اجازه میدهند تا وابستگیها را به طور خودکار تزریق کند. هر سرویس با استفاده از الگوی Scoped ایجاد میشود، به این معنی که یک نمونه جدید برای هر درخواست HTTP ایجاد میشود.
EndPoint.Site => Areas => Admin => Controllers => UsersController.cs
نامفضا (Namespace)
csharp
namespace EndPoint.Site.Areas.Admin.Controllers
این خط، نامفضا (namespace) EndPoint.Site.Areas.Admin.Controllers را تعریف میکند. نامفضاها برای سازماندهی و دستهبندی کدها استفاده میشوند.
استفاده از Area
csharp
[Area("Admin")]
این خط کنترلر را به یک ناحیه (Area) به نام Admin اختصاص میدهد. Areas در ASP.NET Core برای تقسیمبندی منطق برنامه به بخشهای جداگانه استفاده میشود.
تعریف کلاس UsersController
csharp
public class UsersController : Controller
این خط کلاس UsersController را تعریف میکند که از کلاس پایه Controller ارثبری میکند.
متغیرهای خصوصی و سازنده
csharp
private readonly IGetUsersService _getUsersService;
private readonly IGetRolesService _getRolesService;
public UsersController(IGetUsersService getUsersService, IGetRolesService getRolesService)
{
_getUsersService = getUsersService;
_getRolesService = getRolesService;
}
متغیرهای خصوصی: دو متغیر خصوصی از نوع اینترفیسهای IGetUsersService و IGetRolesService تعریف میشوند که برای دریافت کاربران و نقشها استفاده میشوند.
سازنده: سازنده UsersController دو پارامتر از نوع اینترفیسهای ذکر شده را دریافت کرده و آنها را به متغیرهای خصوصی اختصاص میدهد. این پارامترها از طریق DI (Dependency Injection) تزریق میشوند.
متد Index
csharp
public IActionResult Index(string serchKey, int page = 1)
{
return View(_getUsersService.Execute(new RequestGetUserDto
{
Page = page,
SearchKey = serchKey,
}));
}
public IActionResult Index(string serchKey, int page = 1):
این متد برای نمایش صفحه اصلی کاربران استفاده میشود. پارامترهای serchKey و page برای جستجو و صفحهبندی استفاده میشوند.
بازگشت View: این متد نتیجه اجرای متد Execute از سرویس IGetUsersService را به ویو بازمیگرداند. این نتیجه شامل لیستی از کاربران و تعداد کل کاربران است.
متد Create
csharp
[HttpGet]
public IActionResult Create()
{
ViewBag.Roles = new SelectList(_getRolesService.Execute().Data, "Id", "Name");
return View();
}
[HttpGet]:
این اتریبیوت نشان میدهد که این متد فقط برای درخواستهای GET مورد استفاده قرار میگیرد.
public IActionResult Create():
این متد برای نمایش فرم ایجاد کاربر جدید استفاده میشود.
ViewBag.Roles:
این خط نقشها را از سرویس IGetRolesService دریافت کرده و آنها را در ViewBag ذخیره میکند تا در ویو به صورت لیست کشویی نمایش داده شوند.
بازگشت View: این متد ویو Create را نمایش میدهد که شامل فرم ایجاد کاربر جدید است.
نتیجهگیری
این کنترلر UsersController برای مدیریت کاربران در ناحیه Admin استفاده میشود. شامل دو متد اصلی است:
Index:
برای نمایش لیست کاربران با قابلیت جستجو و صفحهبندی.
Create:
برای نمایش فرم ایجاد کاربر جدید و دریافت نقشها از دیتابیس و نمایش آنها به صورت لیست کشویی.
این ساختار کنترلر به شما امکان میدهد تا کاربران و نقشها را به صورت کارآمد مدیریت کنید و از DI برای تزریق وابستگیها استفاده کنید.
در packing manager console عبارت Add-Migration AddRoles و بعد Update-Database وارد کنید
Test_Store 6.zip
حجم:
45.7M
قسمت آخر user ثبت نام و ورود
واقعا ببخشید که کد های من زمان زیادی طول کشید بعدا کد ها را توضیح می دهم
ساختار درختی پوشه و فایل
Test_Store
│
├── Doc
│
├── Src
│ ├── Common
│ │ └── library: Test_Store.Common
│ │ ├── Dto
│ │ │ └── ResultDto.cs
│ │ ├── Roles
│ │ │ └── UserRoles.cs
│ │ ├── Pagination.cs
│ │ └── PasswordHasher.cs
│ │
│ ├──── Core
│ │ ├──── library: Test_Store.Application
│ │ │ ├── Interfaces
│ │ │ │ ├── Contexs
│ │ │ │ │ └── IDataBaseCotex.cs
│ │ │ │ └── FacadPatterns
│ │ │ │ └── IProductFacad.cs
│ │ │ └── Services
│ │ │ ├── Users
│ │ │ │ ├── Commands
│ │ │ │ │ ├── EditUser
│ │ │ │ │ │ └── IEditUserService.cs
│ │ │ │ │ ├── RegisterUser
│ │ │ │ │ │ └── IRegisterUserService.cs
│ │ │ │ │ ├── RemoveUser
│ │ │ │ │ │ ├── IRemoveUserService.cs
│ │ │ │ │ │ └── RemoveUserService.cs
│ │ │ │ │ ├── UserLogin
│ │ │ │ │ │ └── IUserLoginService.cs
│ │ │ │ │ └── UserSatusChange
│ │ │ │ │ └── IUserSatusChangeService.cs
│ │ │ │ └── Queries
│ │ │ │ ├── GetRoles
│ │ │ │ │ ├── GetRolesService.cs
│ │ │ │ │ ├── IGetRolesService.cs
│ │ │ │ │ └── RolesDto.cs
│ │ │ │ └── GetUsers
│ │ │ │ ├── GetUsersDto.cs
│ │ │ │ ├── GetUsersService.cs
│ │ │ │ ├── IGetUsersService.cs
│ │ │ │ ├── RequestGetUserDto.cs
│ │ │ │ └── ReslutGetUserDto.cs
│ │ │ └── Products
│ │ │ ├── Commands
│ │ │ │ └── AddNewCategory
│ │ │ │ └── IAddNewCategoryService.cs
│ │ │ ├── FacadPattern
│ │ │ │ └── ProductFacad.cs
│ │ │ └── Queries
│ │ │ └── GetCategories
│ │ │ └── IGetCategoriesService.cs
│ │ │
│ │ └── library: Test_Store.Domain
│ │ └── Entities
│ │ ├── Users
│ │ │ ├── Role.cs
│ │ │ ├── User.cs
│ │ │ └── UserInRole.cs
│ │ ├── Commons
│ │ │ ├── BaseEntity.cs
│ │ │ └── BaseEntityNotId.cs
│ │ └── Products
│ │ └── Category.cs
│ │
│ ├── Infrastructure
│ │ ├── library: Test_Store.Infrastructure
│ │ └── library: Test_Store.Persistence
│ │ ├── Context
│ │ │ └── DataBaseContext.cs
│ │ └── Migrations
│ │ ├── ......_Users.cs
│ │ └── DataBaseContextModelSnapshot.cs
│ │
│ └── Presentation
│ └── ASP.NET Core: EndPoint.Site
│ │
│ ├── Areas
│ │ └── Admin
│ │ ├── Controllers
│ │ │ └── UsersController.cs
│ │ ├── Views
│ │ │ ├── Shared
│ │ │ │ └── _AdminLayout.cshtml
│ │ │ └── Users
│ │ │ ├── Create.cshtml
│ │ │ └── Index.cshtml
│ │ └── Models
│ ├── Controllers
│ │ ├── AuthenticationController.cs
│ │ └── HomeController.cs
│ ├── Views
│ │ ├── Authentication
│ │ │ ├── Signin.cshtml
│ │ │ └── Signup.cshtml
│ │ ├── Home
│ │ │ ├── Index.cshtml
│ │ │ └── Privacy.cshtml
│ │ ├── Shared
│ │ │ ├── _Layout.cshtml
│ │ │ ├── _ValidationScriptsPartial.cshtml
│ │ │ └── Error.cshtml
│ │ ├── _ViewImports.cshtml
│ │ └── _ViewStart.cshtml
│ ├── Models
│ │ ├── ViewModels
│ │ │ └── AuthenticationViewModel
│ │ │ └── SignupViewModel.cs
│ │ └── ErrorViewModel.cs
│ ├── wwwroot
│ │ ├── AdminTemplate
│ │ ├── css
│ │ ├── js
│ │ ├── lib
│ │ ├── SiteTemplate
│ │ └── favicon.ico
│ └── Program.cs
│
└── Test
Test_Store.Common => PasswordHasher.cs
بیایید با توضیح کد
PasswordHasherکه در کلاس
Test_Store.Common.PasswordHasherقرار دارد، شروع کنیم. این کلاس به منظور هش و تأیید رمز عبورها طراحی شده است و از الگوریتمهای مختلفی استفاده میکند. توضیحات کد: 1. Properties (ویژگیها): -
bool _useAspNetCore: مشخص میکند که آیا از کتابخانه Microsoft.AspNetCore.Cryptography.KeyDerivation استفاده میشود یا خیر. -
byte _formatMarker: نشانگر قالب هش (مانند IdentityV2, IdentityV3, Custom). -
KeyDerivationPrf _prf: تابع اشتقاق کلید مورد استفاده (مانند HMACSHA256). -
HashAlgorithmName _hashAlgorithmName: نام الگوریتم هش مورد استفاده (مانند SHA256). -
bool _includeHeaderInfo: مشخص میکند که آیا اطلاعات پیکربندی در هدر قرار داده میشود یا خیر. -
int _saltLength: طول نمک. -
int _requestedLength: طول کلید مشتق شده. -
int _iterCount: تعداد تکرارهای الگوریتم PBKDF2. 2. Constructor (سازنده): - سازنده کلاس
PasswordHasherپیشفرضها را تنظیم میکند. در این مثال، تنظیمات IdentityV3 با HMACSHA256 و 10000 تکرار استفاده شده است. 3. HashPassword Method (متد HashPassword): - این متد یک رمز عبور را هش میکند. ابتدا یک نمک تولید میکند، سپس کلید مشتق شده (subkey) را با استفاده از PBKDF2 تولید میکند و نهایتاً خروجی به دست آمده را به صورت Base64 بازمیگرداند. 4. VerifyPassword Method (متد VerifyPassword): - این متد رمز عبور ورودی را با رمز عبور هش شده مقایسه میکند. ابتدا رمز عبور هش شده را تجزیه و تحلیل میکند، سپس رمز عبور ورودی را هش میکند و کلیدهای مشتق شده (subkeys) را با هم مقایسه میکند. 5. Helper Methods (متدهای کمکی): -
ByteArraysEqual: دو آرایه بایت را برای برابری مقایسه میکند. -
ReadNetworkByteOrder: خواندن یک مقدار UInt32 از آرایه بایت. -
WriteNetworkByteOrder: نوشتن یک مقدار UInt32 به آرایه بایت. نتیجهگیری: این کلاس به شما کمک میکند تا رمز عبورهای کاربران را به صورت ایمن هش کنید و در پایگاه داده ذخیره کنید. همچنین میتوانید رمز عبورهای ورودی کاربران را با رمز عبورهای ذخیره شده مقایسه کنید و از صحت آنها اطمینان حاصل کنید.
Test_Store.Application => FacadPatterns => IProductFacad.cs
بیایید این اینترفیس
IProductFacadرا بررسی کنیم تا ببینیم که چگونه عمل میکند و چه نیازهایی دارد. بررسی کد: 1. تعریف اینترفیس `IProductFacad`: - این اینترفیس دو پراپرتی شامل
AddNewCategoryServiceو
GetCategoriesServiceدارد. - این دو پراپرتی به سرویسهای مربوط به افزودن دستهبندی جدید و دریافت دستهبندیها اشاره دارند. کد: csharp public interface IProductFacad { AddNewCategoryService AddNewCategoryService { get; } IGetCategoriesService GetCategoriesService { get; } } مفاهیم مرتبط: 1. پراپرتی `AddNewCategoryService`: - این پراپرتی به یک کلاس سرویس به نام
AddNewCategoryServiceاشاره دارد که مسئولیت افزودن دستهبندی جدید را بر عهده دارد. 2. پراپرتی `GetCategoriesService`: - این پراپرتی به یک اینترفیس سرویس به نام
IGetCategoriesServiceاشاره دارد که مسئولیت دریافت دستهبندیها را بر عهده دارد. نتیجهگیری: این اینترفیس به نوعی الگوی طراحی Facade را پیادهسازی میکند که به شما امکان میدهد تا مجموعهای از سرویسهای مرتبط را از طریق یک نقطه ورود واحد مدیریت کنید.
Test_Store => Application => Services => Products => Commands => AddNewCategory => IAddNewCategoryService.cs
بیایید با هم کد AddNewCategoryService را بررسی کنیم. این کد به منظور افزودن یک دستهبندی جدید به فروشگاه شما طراحی شده است.
توضیحات کد:
Interface IAddNewCategoryService:
اینترفیس IAddNewCategoryService یک متد Execute را تعریف میکند که یک دستهبندی جدید را به دیتابیس اضافه میکند. این متد دو پارامتر میپذیرد: ParentId که شناسه دستهبندی والد است (در صورت وجود) و Name که نام دستهبندی جدید است. این متد یک شیء ResultDto برمیگرداند که حاوی وضعیت و پیام نتیجه عملیات است.
Class AddNewCategoryService:
کلاس AddNewCategoryService پیادهسازی اینترفیس IAddNewCategoryService است.
Constructor (سازنده):
سازنده کلاس AddNewCategoryService که یک شیء از نوع IDataBaseContext را دریافت میکند. این شیء برای دسترسی به دیتابیس استفاده میشود.
Method Execute:
این متد مسئول اجرای عملیات افزودن دستهبندی جدید است. ابتدا بررسی میکند که آیا Name خالی یا null است. اگر خالی باشد، یک پیام خطا برمیگرداند.
سپس یک شیء از نوع Category ایجاد میکند و نام دستهبندی و دستهبندی والد (در صورت وجود) را تنظیم میکند.
این دستهبندی جدید را به دیتابیس اضافه میکند و تغییرات را ذخیره میکند.
در نهایت، یک پیام موفقیتآمیز برمیگرداند.
Method GetParent:
این متد مسئول یافتن دستهبندی والد با استفاده از ParentId است. اگر ParentId موجود باشد، دستهبندی والد را از دیتابیس پیدا میکند و برمیگرداند.
نتیجهگیری:
این کد به شما امکان میدهد تا دستهبندیهای جدید را به دیتابیس خود اضافه کنید و در صورت وجود، دستهبندی والد را نیز تنظیم کنید. این فرآیند به شما کمک میکند تا ساختار دستهبندیهای فروشگاه خود را بهبود بخشید و مدیریت کنید.
Test_Store => Application => Services => Products => FacadPattern => ProductFacad.cs
بیایید کد ProductFacad را بررسی کنیم. این کلاس به منظور مدیریت الگوی فاساد (Facad Pattern) برای عملیات مرتبط با محصولات طراحی شده است. فاساد پترن یکی از الگوهای طراحی است که به منظور سادهسازی و یکپارچهسازی دسترسی به سیستمهای پیچیده استفاده میشود.
توضیحات کد:
Namespace و Interface:
namespace Test_Store.Application.Services.Products.FacadPattern:
نامفضا برای سازماندهی کدها.
IProductFacad:
اینترفیس مربوط به کلاس ProductFacad.
Class ProductFacad:
این کلاس پیادهسازی اینترفیس IProductFacad است.
Constructor (سازنده):
سازنده کلاس ProductFacad که یک شیء از نوع IDataBaseContext را دریافت میکند. این شیء برای دسترسی به دیتابیس استفاده میشود.
Property AddNewCategoryService:
این Property یک شیء از نوع AddNewCategoryService را برمیگرداند. در صورتی که این شیء از قبل ایجاد نشده باشد، یک نمونه جدید از آن ایجاد میکند.
استفاده از الگوی Singleton برای اطمینان از این که تنها یک نمونه از AddNewCategoryService وجود دارد.
Property GetCategoriesService:
این Property یک شیء از نوع IGetCategoriesService را برمیگرداند. در صورتی که این شیء از قبل ایجاد نشده باشد، یک نمونه جدید از آن ایجاد میکند.
استفاده از الگوی Singleton برای اطمینان از این که تنها یک نمونه از GetCategoriesService وجود دارد.
مزایای استفاده از Facad Pattern:
سادگی و یکنواختی:
فاساد پترن به شما اجازه میدهد تا یک رابط ساده و یکنواخت برای عملیات پیچیده ایجاد کنید.
نگهداری آسان:
با استفاده از این الگو، تغییرات و نگهداری کدها سادهتر میشود، زیرا تمامی دسترسیها از طریق یک نقطه (فاساد) انجام میشود.
افزایش انعطافپذیری:
این الگو به شما امکان میدهد تا به راحتی سرویسهای جدیدی اضافه کنید یا سرویسهای موجود را تغییر دهید، بدون این که تغییرات زیادی در سایر قسمتهای برنامه اعمال شود.
نتیجهگیری:
کلاس ProductFacad به شما اجازه میدهد تا عملیات مرتبط با محصولات را سادهتر مدیریت کنید و دسترسی به سرویسهای مختلف مانند AddNewCategoryService و GetCategoriesService را یکپارچه کنید. این کلاس با استفاده از الگوی Singleton اطمینان حاصل میکند که تنها یک نمونه از هر سرویس ایجاد میشود.
Test_Store => Application => Services => Products => Queries => GetCategories => IGetCategoriesService.cs
بیایید کد GetCategoriesService را بررسی کنیم. این کد به منظور دریافت لیست دستهبندیها طراحی شده است و شامل اینترفیس، کلاس سرویس، و چند DTO میشود.
توضیحات کد:
Interface IGetCategoriesService:
این اینترفیس یک متد Execute را تعریف میکند که لیست دستهبندیها را بر اساس ParentId برمیگرداند. این متد یک شیء ResultDto شامل لیستی از CategoriesDto را برمیگرداند.
Class GetCategoriesService:
کلاس GetCategoriesService پیادهسازی اینترفیس IGetCategoriesService است.
Constructor:
سازنده کلاس که یک شیء از نوع IDataBaseContext دریافت میکند. این شیء برای دسترسی به دیتابیس استفاده میشود.
Method Execute:
این متد لیست دستهبندیها را بر اساس ParentId برمیگرداند. ابتدا دستهبندیها را از دیتابیس دریافت میکند، سپس آنها را به لیست CategoriesDto تبدیل میکند و نهایتاً نتیجه را برمیگرداند.
DTO Classes:
CategoriesDto:
این کلاس نمایشی از یک دستهبندی شامل Id, Name, HasChild, و Parent است.
ParentCategoryDto:
این کلاس نمایشی از دستهبندی والد شامل Id و name است.
نحوه عملکرد Execute Method:
دریافت دستهبندیها از دیتابیس:
ابتدا دستهبندیها را با استفاده از Include (برای بارگذاری دستهبندی والد و زیر دستهها) و Where (برای فیلتر کردن بر اساس ParentId) از دیتابیس دریافت میکند.
تبدیل به DTO:
سپس دستهبندیها را به لیست CategoriesDto تبدیل میکند. در هر CategoriesDto، اطلاعات مربوط به دستهبندی مانند Id, Name, Parent (در صورت وجود)، و HasChild (برای بررسی وجود زیر دستهها) ذخیره میشود.
بازگرداندن نتیجه:
نهایتاً یک شیء ResultDto شامل لیست دستهبندیها، وضعیت موفقیتآمیز بودن عملیات، و یک پیام برگردانده میشود.
نتیجهگیری:
این کد به شما کمک میکند تا به راحتی لیست دستهبندیها را بر اساس ParentId دریافت کنید و آنها را به صورت DTO بازگردانید. این روش به شما امکان میدهد تا دادهها را به شکل مورد نیاز در لایههای مختلف برنامه نمایش دهید.