ایجاد کنترلر و نام کنترلر: CustomerController.cs و کد های زیر
public class CustomerController : Controller
{
private readonly IGetCustomerListService _getCustomerListService;
public CustomerController(IGetCustomerListService getCustomerListService)
{
_getCustomerListService = getCustomerListService;
}
// GET: CustomerController
public ActionResult Index()
{
return View(_getCustomerListService.Execute());
}
بیایید کد شما را به تفصیل بررسی کنیم و هر بخش از آن را توضیح دهیم:
تعریف کلاس کنترلر
public class CustomerController : Controller
{
public class CustomerController :
Controller:
این بخش نشان میدهد که CustomerController یک کلاس عمومی است که از کلاس Controller به ارث برده است. در ASP.NET Core، کنترلرها مسئول مدیریت درخواستهای HTTP و برگرداندن پاسخ مناسب به کاربر هستند.
تعریف فیلد خصوصی برای سرویس
private readonly IGetCustomerListService _getCustomerListService;
private readonly IGetCustomerListService
_getCustomerListService:
این خط یک فیلد خصوصی و فقط خواندنی (readonly) به نام _getCustomerListService از نوع اینترفیس IGetCustomerListService تعریف میکند. این فیلد برای نگهداری یک نمونه از سرویس IGetCustomerListService استفاده میشود.
سازنده کلاس
public CustomerController(IGetCustomerListService getCustomerListService)
{
_getCustomerListService = getCustomerListService;
}
public
CustomerController(IGetCustomerListService getCustomerListService):
این سازنده کلاس CustomerController است که یک پارامتر از نوع IGetCustomerListService دریافت میکند.
_getCustomerListService = getCustomerListService:
در داخل سازنده، نمونهای از IGetCustomerListService که از طریق تزریق وابستگی (Dependency Injection) دریافت شده است، به فیلد خصوصی _getCustomerListService اختصاص داده میشود. این روش به کنترلر اجازه میدهد تا از سرویس IGetCustomerListService استفاده کند.
متد Index
// GET: CustomerController
public ActionResult Index()
{
return View(_getCustomerListService.Execute());
}
}
public ActionResult Index():
این متد یک اکشن به نام Index در کنترلر CustomerController تعریف میکند. این اکشن زمانی اجرا میشود که درخواست GET به آدرس /Customer ارسال شود.
return View(_getCustomerListService.Execute()):
این خط یک ویو (View) را برمیگرداند و دادههای مشتریان را که از طریق متد Execute در سرویس _getCustomerListService بازیابی شدهاند، به ویو ارسال میکند. متد Execute یک لیست از CustomerListDto بازمیگرداند که به ویو ارسال میشود تا نمایش داده شود.
خلاصه
کد شما یک کنترلر به نام CustomerController ایجاد میکند که شامل یک اکشن به نام Index است. این کنترلر از یک سرویس IGetCustomerListService استفاده میکند تا لیستی از مشتریان را بازیابی کرده و آن را به ویو ارسال کند. با استفاده از تزریق وابستگی، نمونهای از سرویس IGetCustomerListService به کنترلر تزریق میشود و از آن برای اجرای منطق بازیابی دادهها استفاده میشود.
این ساختار به شما کمک میکند تا منطق کسب و کار را از منطق ارائه (presentation logic) جدا کنید و کد خود را ماژولار و تستپذیر کنید.
context.Product.Add() و context.Product.AddAsync() و context.Product.AddRange() و context.Product.Attach() و context.Product.Remove() و context.Product.RemoveRange() , context.Product.Find()
بیایید هر یک از این متدها را که در هنگام کار با DbContext در Entity Framework Core استفاده میشوند، بررسی کنیم. این متدها به شما کمک میکنند تا عملیات مختلفی را روی موجودیتها (entities) انجام دهید.
1. context.Products.Add()
این متد برای اضافه کردن یک موجودیت جدید به مجموعهی Products استفاده میشود. این موجودیت به حالت "اضافه شده" تغییر پیدا میکند و در زمان اجرای SaveChanges به پایگاه داده اضافه میشود.
public IActionResult Create(Product product)
{
if (ModelState.IsValid)
{
_context.Products.Add(product);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return View(product);
}
2. context.Products.AddAsync()
این متد مشابه Add است، اما نسخهی غیرهمزمان (async) آن است که در مواردی که نیاز به استفاده از عملیاتهای غیرهمزمان (asynchronous) دارید، استفاده میشود. این متد یک Task برمیگرداند.
public async Task<IActionResult> CreateAsync(Product product)
{
if (ModelState.IsValid)
{
await _context.Products.AddAsync(product);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(product);
}
3. context.Products.AddRange()
این متد برای اضافه کردن مجموعهای از موجودیتها به صورت همزمان استفاده میشود. تمامی موجودیتها به حالت "اضافه شده" تغییر پیدا میکنند و در زمان اجرای SaveChanges به پایگاه داده اضافه میشوند.
public IActionResult CreateMultiple(List<Product> products)
{
if (ModelState.IsValid)
{
_context.Products.AddRange(products);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return View(products);
}
4. context.Products.Attach()
این متد برای "اتصال" یک موجودیت به کانتکست استفاده میشود. این متد موجودیت را به کانتکست اضافه میکند بدون اینکه حالت آن را تغییر دهد. این متد معمولاً برای سناریوهایی استفاده میشود که موجودیت در حال حاضر در پایگاه داده وجود دارد و شما میخواهید تغییراتی را در آن اعمال کنید.
public IActionResult Edit(Product product)
{
if (ModelState.IsValid)
{
_context.Products.Attach(product);
_context.Entry(product).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return View(product);
}
5. context.Products.Remove()
این متد برای حذف یک موجودیت از مجموعهی Products استفاده میشود. موجودیت به حالت "حذف شده" تغییر پیدا میکند و در زمان اجرای SaveChanges از پایگاه داده حذف میشود.
public IActionResult Delete(long id)
{
var product = _context.Products.Find(id);
if (product != null)
{
_context.Products.Remove(product);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return NotFound();
}
6. context.Products.RemoveRange()
این متد برای حذف مجموعهای از موجودیتها به صورت همزمان استفاده میشود. تمامی موجودیتها به حالت "حذف شده" تغییر پیدا میکنند و در زمان اجرای SaveChanges از پایگاه داده حذف میشوند.
public IActionResult DeleteMultiple(List<long> ids)
{
var products = _context.Products.Where(p => ids.Contains(p.Id)).ToList();
if (products.Any())
{
_context.Products.RemoveRange(products);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return NotFound();
}
7. context.Products.Find()
این متد برای یافتن یک موجودیت با استفاده از کلید اصلی آن استفاده میشود. اگر موجودیت پیدا شود، برگردانده میشود؛ در غیر این صورت، مقدار null برمیگردد.
public IActionResult Details(long id)
{
var product = _context.Products.Find(id);
if (product != null)
{
return View(product);
}
return NotFound();
}
نتیجهگیری
این متدها به شما کمک میکنند تا عملیات مختلفی مانند ایجاد، ویرایش، حذف، و یافتن موجودیتها را در پایگاه داده انجام دهید. با استفاده از این متدها، میتوانید به سادگی دادههای خود را مدیریت کنید و تغییرات را به پایگاه داده اعمال کنید.
SQL Server Profiler
یک ابزار تجزیه و تحلیل و ردیابی است که توسط Microsoft برای SQL Server توسعه داده شده است. این ابزار به شما اجازه میدهد تا فعالیتها و عملیاتی که در یک پایگاه داده SQL Server انجام میشوند را ردیابی کرده و آنها را تجزیه و تحلیل کنید.
ویژگیهای SQL Server Profiler:
ردیابی فعالیتها: شما میتوانید تمامی فعالیتها و عملیاتی که در پایگاه داده انجام میشوند را ردیابی کنید.
انتخاب و اعمال فیلتر: شما میتوانید فیلترهای مختلفی را برای ردیابی فعالیتهای خاص اعمال کنید.
اختلاط و تجزیه و تحلیل دادهها: دادههای ردیابی میتوانند در فایل یا جدول ذخیره شده و بعداً تجزیه و تحلیل شوند.
استفاده در تشخیص مشکلات: این ابزار میتواند به شما کمک کند تا مشکلات مرتبط با عملکرد پایگاه داده را تشخیص دهید و رفع کنید.
کاربردها:
ردیابی و تشخیص مشکلات: برای ردیابی و تشخیص مشکلات مرتبط با عملکرد پایگاه داده.
مرور عملکرد: برای مرور عملکرد پایگاه داده و تعیین کدام عملیات ممکن است عملکرد را تحت تأثیر قرار بگیرند.
تجزیه و تحلیل عملیات: برای تجزیه و تحلیل عملیات و فعالیتهای مختلف در پایگاه داده.
ملاحظات:
استفاده از تجسمهای گسترده (Extended Events): از آینده به عنوان جایگزینی برای SQL Server Profiler پیشنهاد میشود.
بیایید به بررسی معماری سه لایه سنتی (Three-Tier Architecture)، ساخت معماری توسط توسعهدهندگان، و معماری کلین (Clean Architecture) بپردازیم و تفاوتها و مزایای هر یک را توضیح دهیم.
معماری سه لایه سنتی (Three-Tier Architecture)
معماری سه لایه یکی از الگوهای معماری رایج برای ساخت برنامههای کاربردی است که شامل سه لایه اصلی میباشد:
لایه ارائه (Presentation Layer):
این لایه مسئول تعامل با کاربران است و شامل رابطهای کاربری مانند وبصفحات، اپلیکیشنهای موبایل و دسکتاپ میباشد.
نمونه: کنترلرها و ویوها در ASP.NET MVC.
لایه منطق کسب و کار (Business Logic Layer):
این لایه شامل منطق کسب و کار و فرآیندهای اصلی برنامه است که عملیات دادهها و قوانین کسب و کار را مدیریت میکند.
نمونه: سرویسها و کلاسهای کسب و کار.
لایه دسترسی به دادهها (Data Access Layer):
این لایه مسئول دسترسی به پایگاه داده و عملیات CRUD (ایجاد، خواندن، بهروزرسانی، حذف) است.
نمونه: مخازن (Repositories) و DbContext در Entity Framework.
ساخت معماری توسط توسعهدهندگان
توسعهدهندگان معمولاً بر اساس نیازهای پروژه و ترجیحات شخصی خود، معماری پروژه را تنظیم و پیادهسازی میکنند. این میتواند ترکیبی از الگوهای مختلف معماری باشد، مانند:
معماری چند لایه (N-Tier Architecture): شامل بیش از سه لایه برای جداسازی بهتر مسئولیتها.
معماری میکروسرویسها (Microservices Architecture): هر سرویس به صورت مستقل و خودکفا پیادهسازی میشود و از طریق APIها با یکدیگر تعامل دارند.
معماری بدون سرور (Serverless Architecture): استفاده از سرویسهای ابری که به صورت خودکار مدیریت منابع را انجام میدهند.
معماری کلین (Clean Architecture)
معماری کلین (Clean Architecture) توسط رابرت سی. مارتین (معروف به عمو باب) معرفی شده است و بر اصول طراحی و جداسازی مسئولیتها تأکید دارد. این معماری شامل چهار لایه اصلی است:
لایه دامنه موجودیتها (Entities):
شامل مدلهای دامنه و قوانین کسب و کار بنیادی است.
مستقل از فریمورکها و تکنولوژیها.
لایه موارد استفاده (Use Cases):
شامل منطق خاص کسب و کار و جریانهای کاری است که از موجودیتها استفاده میکنند.
مستقل از رابطهای کاربری و سیستمهای خارجی.
لایه رابطها (Interface Adapters):
شامل تبدیل دادهها بین لایه دامنه و لایههای خارجی مانند پایگاه داده، UI، و سرویسهای خارجی است.
نمونه: کنترلرها، ویوها، مبدلها (mappers).
لایه فریمورکها و درایورها (Frameworks and Drivers):
شامل جزئیات فنی و زیرساختی مانند پایگاه داده، وبسرور، فریمورکهای UI.
وابسته به فریمورکهای خاص و تکنولوژیها.
مزایا و تفاوتها:
جداسازی مسئولیتها: معماری کلین به جداسازی دقیق مسئولیتها تاکید دارد، در حالی که معماری سه لایه به سادهسازی و جداسازی منطقی ترکتها پرداخته است.
استقلال تکنولوژیک: معماری کلین تاکید بیشتری بر استقلال از فریمورکها و تکنولوژیها دارد.
نگهداری و تستپذیری: معماری کلین به دلیل جداسازی بهتر، نگهداری و تستپذیری بهتری دارد.
نتیجهگیری
هر یک از این معماریها مزایا و کاربردهای خاص خود را دارند و انتخاب مناسب بین آنها بستگی به نیازهای پروژه و تیم توسعهدهنده دارد. معماری سه لایه برای پروژههای ساده و متوسط مناسب است، در حالی که معماری کلین برای پروژههای پیچیده و بلندمدت که نیاز به نگهداری و توسعه آسان دارند، توصیه میشود.
معماری کلین (Clean Architecture) یک الگوی طراحی نرمافزار است که توسط رابرت سی. مارتین (معروف به عمو باب) معرفی شده است. این معماری بر جداسازی دقیق مسئولیتها و استقلال از فریمورکها و تکنولوژیها تاکید دارد و به شما کمک میکند تا نرمافزارهای قابل نگهداری و مقیاسپذیر ایجاد کنید.
لایههای معماری کلین
معماری کلین شامل چهار لایه اصلی است:
لایه دامنه موجودیتها (Entities Layer):
توضیح: این لایه شامل مدلهای دامنه (Domain Models) و قوانین کسبوکار بنیادی است. موجودیتها کلاسهایی هستند که قواعد و منطق کسبوکار را در بر میگیرند و معمولاً مستقل از فریمورکها و تکنولوژیهای خارجی هستند.
مثال: کلاسهای Customer، Product، و Order که شامل خواص و متدهایی هستند که منطق کسبوکار را پیادهسازی میکنند.
public class Customer
{
public long Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
// سایر خواص و متدها
}
لایه موارد استفاده (Use Cases Layer):
توضیح: این لایه شامل موارد استفاده یا همان یوزکیسها است که منطق خاص کسبوکار و جریانهای کاری را پیادهسازی میکنند. این لایه به موجودیتها وابسته است و از آنها استفاده میکند، اما مستقل از رابطهای کاربری و سیستمهای خارجی است.
مثال: یک سرویس برای مدیریت مشتریان که شامل متدهای ایجاد، خواندن، بهروزرسانی و حذف مشتریان است.
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
public void AddCustomer(Customer customer)
{
_customerRepository.Add(customer);
}
// سایر متدها برای مدیریت مشتریان
}
لایه رابطها (Interface Adapters Layer):
توضیح: این لایه شامل مبدلها (adapters) و تبدیلکنندهها (converters) است که دادهها را بین لایه دامنه و لایههای خارجی مانند پایگاه داده، UI، و سرویسهای خارجی تبدیل میکنند. این لایه به عنوان پل ارتباطی بین لایههای داخلی و خارجی عمل میکند.
مثال: کنترلرها در ASP.NET Core، مبدلهای DTO، و رپوزیتوریها.
public class CustomerController : Controller
{
private readonly CustomerService _customerService;
public CustomerController(CustomerService customerService)
{
_customerService = customerService;
}
public IActionResult Index()
{
var customers = _customerService.GetAllCustomers();
return View(customers);
}
// سایر اکشنها
}
لایه فریمورکها و درایورها (Frameworks and Drivers Layer):
توضیح: این لایه شامل جزئیات فنی و زیرساختی است که برای اجرای برنامه نیاز است، مانند پایگاه داده، وبسرور، و فریمورکهای UI. این لایه وابسته به فریمورکها و تکنولوژیهای خاص است.
مثال: پیکربندی Entity Framework Core برای اتصال به پایگاه داده، تنظیمات ASP.NET Core.
public class DatabaseContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("ConnectionString");
}
}
مزایای معماری کلین
استقلال از فریمورکها: این معماری به شما اجازه میدهد تا تغییرات در فریمورکها و تکنولوژیها بدون نیاز به تغییر در منطق کسبوکار خود انجام دهید.
قابلیت نگهداری و تستپذیری بالا: به دلیل جداسازی مسئولیتها، نگهداری و تست کدها بسیار سادهتر و مؤثرتر است.
ماژولار بودن: این معماری باعث میشود که برنامهها به صورت ماژولار طراحی شوند که به توسعهدهندگان اجازه میدهد بخشهای مختلف برنامه را به صورت مستقل توسعه و نگهداری کنند.
نتیجهگیری
معماری کلین یک الگوی طراحی قدرتمند است که به شما کمک میکند تا نرمافزارهایی با کیفیت بالا، قابل نگهداری و تستپذیر ایجاد کنید. با استفاده از این معماری، میتوانید از جداسازی مسئولیتها، استقلال از فریمورکها و تکنولوژیها، و ماژولار بودن بهرهمند شوید.