قبلا و در دو پست جداگانه در خصوص موارد زیر صحبت کردیم. این پست در ادامه تکمیل مباحث زیر می باشد
پیاده سازی الگوی Repository در ASP.NET Core
پياده سازي Aggregate در Domin Layer - DDD
برای هر Aggregate Root، باید یک کلاس Repository ایجاد کنید. در یک برنامه مبتنی بر الگوهای طراحی دامنه محور (DDD)، تنها کانالی که باید برای به روز رسانی پایگاه داده استفاده کنید باید Repositoryها باشند. این به این دلیل است که آنها یک رابطه یک به یک با Aggregate Root دارند، که invariantهای Aggregate و transactional consistency را کنترل می کند.
پرس و جو(Query) از پایگاه داده از طریق کانال های دیگر اشکالی ندارد (همانطور که می توانید با رویکرد CQRS انجام دهید)، زیرا پرس و جوها وضعیت پایگاه داده را تغییر نمی دهند. با این حال، منطقه تراکنشی (یعنی به روز رسانی ها) همیشه باید توسط Repository و Aggregate Root ها کنترل شود.
اساساً یک Repository به شما امکان می دهد داده هایی را که از پایگاه داده به شکل موجودیت های دامنه می آیند در حافظه بارگذاری کنید. هنگامی که موجودیت ها در حافظه هستند، می توان آنها را تغییر داد و سپس از طریق تراکنش ها به پایگاه داده بازگرداند.
همانطور که قبلاً ذکر شد، اگر از الگوی معماری CQS/CQRS استفاده می کنید، این پرسوجوها با invariantهای موجود در Aggregateها محدود نمیشوند. این داده ها به لایه presentation یا client app
می رود.
اگر کاربر تغییراتی ایجاد کند، داده هایی که باید به روز شوند از client app یا لایه presentation به
لایه application (مانند سرویس Web API) می آیند. هنگامی که commandی را در یک
command handler دریافت می کنید، از Repository برای دریافت داده هایی که می خواهید از پایگاه داده به روز کنید استفاده می کنید. شما آن را در حافظه با داده های ارسال شده با دستورات به روز می کنید و سپس داده ها (domain entities) را در پایگاه داده از طریق یک تراکنش اضافه یا به روز می کنید.
مهم است که مجدداً تأکید کنم، همانطور که در شکل زیر نشان داده شده است باید برای هر
Aggregate Root فقط یک Repository تعریف کنید. برای دستیابی به هدف Aggregate Root یعنی حفظ transactional consistency بین تمام اشیاء موجود در Aggregate ، هرگز نباید برای هر جدول در پایگاه داده یک Repository ایجاد کنید.
پیاده سازی طراحی Repository به گونه ای می تواند ارزشمند باشد که این قانون را اجرا کند که فقط
Aggregate Rootها باید دارای Repository باشند. می توانید یک نوع generic یا base repository ایجاد کنید که نوع موجودیت هایی را که با آنها کار می کند محدود می کند تا اطمینان حاصل شود که اینفرفیس نشانگر(marker interface) IAggregateRoot را دارند.
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories { public class OrderRepository : IOrderRepository { // ... } }
public interface IOrderRepository : IRepository<Order> { Order Add(Order order); // ... }
به این ترتیب، واضح است که شما از یک Repository برای هدف قرار دادن یک Aggregate خاص استفاده می کنید. این کار را می توان به راحتی با پیاده سازی یک رابط پایه generic IRepository مانند کد زیر انجام داد:
public interface IRepository<T> where T : IAggregateRoot { //.... }
توصیه میشود اینترفیس های Repository را در لایه domain model تعریف و قرار دهید تا لایه application، مانند Web API شما، مستقیماً به لایه infrastructure که در آن پیادهسازی واقعی را انجام دادهاید، بستگی نداشته باشد.
توجه کنید همانطور که در این لینک به آن پرداخته شده است این یک الگوی ضروری برای پیاده سازی در طراحی DDD یا حتی به طور کلی توسعه دات نت نیست.Repository ها ممکن است مفید باشند، اما برای طراحی DDD شما حیاتی نیستند.
به هر حال، هر زمان که از EF Core استفاده می کنید، از الگوی Repository استفاده خواهید کرد(مطابق مستندات مایکروسافت کلاس DbContext الگوهای Unit of Work و Repository را پیادهسازی میکند)
بیشتر بخوانید : آیا بهمراه الگوی CQRS باید از الگوی Repository استفاده کنیم؟
بيشتر بخوانيد : الگوی Specification در ASP.NET Core - بهبود Generic Repository Pattern
بیشتر بخوانید : Implementing DDD - Clean Architecture
بیشتر بخوانید : نقشه راه توسعه دهندگان Asp.NET Core