معماری پیاز یا Onion Architecture یک الگوی طراحی نرم افزاری است که با سازماندهی کدها در لایه ها به ایجاد برنامه های کاربردی متصل و قابل نگهداری کمک می کند.در این مقاله با مثال به توضیح معماری پیاز می پردازیم.

نمای کلی معماری پیاز
- هسته: در مرکز معماری لایه دامنه قرار دارد که شامل منطق تجاری و مدل های دامنه است.
- لایه دامنه: این لایه شامل موجودیت ها، اشیاء ارزش و خدمات دامنه است. این قلب برنامه است و شامل قوانین اصلی تجارت است.
- لایه سرویس: در اطراف لایه دامنه، لایه سرویس شامل سرویس های کاربردی است که منطق دامنه را هماهنگ می کند و با لایه دامنه تعامل دارد.
- لایه مخزن: این لایه یک انتزاع بر روی دسترسی به داده ها را فراهم می کند و به برنامه اجازه می دهد بدون اینکه به یک فناوری پایگاه داده خاص مرتبط باشد با پایگاه داده تعامل داشته باشد.
- لایه زیرساخت: خارجی ترین لایه شامل اجزای زیرساخت مانند زمینه های پایگاه داده، پیاده سازی دسترسی به داده ها و خدمات خارجی است.
مزایای معماری پیاز
- اتصال شل: لایهها از طریق رابطها تعامل دارند و تغییر پیادهسازیها را بدون تأثیرگذاری بر سایر بخشهای برنامه آسانتر میکنند.
- تست پذیری: قابلیت تست بالا به دلیل وارونگی وابستگی و استفاده از رابط ها.
- قابلیت نگهداری: تفکیک واضح نگرانیها نگهداری و گسترش پایگاه کد را آسانتر میکند.
- انعطافپذیری: حذف پیادهسازیها یا اضافه کردن ویژگیهای جدید بدون تغییر مجدد عمده آسانتر است.
پیاده سازی Onion Architecture در ASP.NET Core
برای پیاده سازی Onion Architecture در ASP.NET Core، می توانید مراحل زیر را دنبال کنید:
1- ایجاد پروژه برای هر لایه: پروژه های جداگانه ای را برای لایه های دامنه، سرویس، مخزن و زیرساخت تنظیم کنید.
2- تعریف اینترفیس ها: برای هر لایه برای اطمینان از اتصال شل، رابط هایی تعریف کنید.
3- پیاده سازی رابط ها: این رابط ها را در پروژه های مربوطه پیاده سازی کنید.
4- Dependency Injection: از تزریق وابستگی داخلی ASP.NET Core برای مدیریت وابستگی ها بین لایه ها استفاده کنید.
5- پیکربندی خدمات: سرویس ها را در فایل Startup.cs پیکربندی کنید تا پیاده سازی ها را ثبت کنید.
پیاده سازی گام به گام معماری پیاز در ASP.NET Core
1. برای هر لایه پروژه ایجاد کنید
با ایجاد چندین پروژه در راه حل خود برای نمایش هر لایه از معماری پیاز شروع کنید:
- Domain: شامل منطق و موجودیت های اصلی کسب و کار شما است.
- Application: شامل خدمات برنامه، DTOها و رابط های شما می باشد.
- Infrastructure: شامل دسترسی به داده و پیاده سازی خدمات خارجی است.
- Web: حاوی لایه ارائه (پروژه ASP.NET Core) است.
2. لایه Domain را تعریف کنید
لایه دامنه هسته برنامه شما است که در آن نهادها و رابط های تجاری خود را تعریف می کنید.
مثال:
namespace Domain.Entities { public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } } namespace Domain.Interfaces { public interface IProductRepository { IEnumerable<Product> GetAll(); Product GetById(int id); void Add(Product product); void Update(Product product); void Delete(int id); } }
3. لایه Application را تعریف کنید
لایه برنامه شامل رابط های سرویس و DTO هایی است که با لایه دامنه تعامل دارند.
مثال:
namespace Application.Interfaces { public interface IProductService { IEnumerable<ProductDto> GetAllProducts(); ProductDto GetProductById(int id); void AddProduct(ProductDto product); void UpdateProduct(ProductDto product); void DeleteProduct(int id); } } namespace Application.DTOs { public class ProductDto { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } }
4. لایه Application Services را پیاده سازی کنید
خدمات برنامه را در لایه برنامه پیاده سازی کنید و رابط های دامنه را تزریق کنید.
مثال:
namespace Application.Services { public class ProductService : IProductService { private readonly IProductRepository _productRepository; public ProductService(IProductRepository productRepository) { _productRepository = productRepository; } public IEnumerable<ProductDto> GetAllProducts() { var products = _productRepository.GetAll(); return products.Select(p => new ProductDto { Id = p.Id, Name = p.Name, Price = p.Price }); } public ProductDto GetProductById(int id) { var product = _productRepository.GetById(id); if (product == null) return null; return new ProductDto { Id = product.Id, Name = product.Name, Price = product.Price }; } public void AddProduct(ProductDto product) { var newProduct = new Product { Name = product.Name, Price = product.Price }; _productRepository.Add(newProduct); } public void UpdateProduct(ProductDto product) { var existingProduct = _productRepository.GetById(product.Id); if (existingProduct == null) return; existingProduct.Name = product.Name; existingProduct.Price = product.Price; _productRepository.Update(existingProduct); } public void DeleteProduct(int id) { _productRepository.Delete(id); } } }
5. لایه Infrastructure را تعریف کنید
لایه زیرساخت شامل پیاده سازی دسترسی به داده و سایر پیاده سازی های سرویس خارجی است.
مثال:
namespace Infrastructure.Data { public class ProductRepository : IProductRepository { private readonly AppDbContext _context; public ProductRepository(AppDbContext context) { _context = context; } public IEnumerable<Product> GetAll() { return _context.Products.ToList(); } public Product GetById(int id) { return _context.Products.Find(id); } public void Add(Product product) { _context.Products.Add(product); _context.SaveChanges(); } public void Update(Product product) { _context.Products.Update(product); _context.SaveChanges(); } public void Delete(int id) { var product = _context.Products.Find(id); if (product != null) { _context.Products.Remove(product); _context.SaveChanges(); } } } }
6. تزریق وابستگی را پیکربندی کنید
خدمات و مخازن را در ظرف تزریق وابستگی هسته ASP.NET ثبت کنید.
مثال:
public class Startup { public void ConfigureServices(IServiceCollection services) { // Register the application services and repositories services.AddScoped<IProductService, ProductService>(); services.AddScoped<IProductRepository, ProductRepository>(); // Other service configurations services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
منابع
Code Maze - Onion Architecture در ASP.NET Core: راهنمای دقیق پیاده سازی Onion Architecture در ASP.NET Core.
CodewithMukesh - Onion Architecture در ASP.NET Core با CQRS: مقاله ای جامع با مثال ها و کد منبع.
GitHub - Onion Architecture Examples: پروژه های متن باز و نمونه هایی از Onion Architecture در ASP.NET Core.