Unit of Work و Repository Pattern شرح عملي سهل

x32x01
  • بواسطة x32x01 ||
بص يا صديقي… الموضوع بدأ معايا تقريبًا في مشروع e-commerce.
كان مشروع كبير، وفيه عمليات كتير بتحصل على الداتابيز كل ثانية.
في مرة من المرات 😅
واحد من اليوزرز عمل Order جديد.
فأنا كمهندس محترم دخلت أضيف الـ Order… وهنا الكارثة حصلت.

أضفت الطلب، تمام.
جيت أقلل كمية المنتج من المخزون… حصل Error.
النتيجة؟
الـ Order اتسجّل، لكن كمية المنتج مقلتش.
يعني الداتا باظت 💥
وبقينا في وضع "هو اشترى حاجة مش موجودة أصلاً" 🙃

وساعتها فهمت إن الموضوع محتاج تنظيم بحت.
مش مجرد SaveChanges() وخلاص.
لا… الموضوع محتاج نظام يضمن إن العملية كلها يا تتم صح… يا متحصلش من الأساس.

وهنا بيظهر بقى دور:
  • Unit of Work
  • Repository Pattern
والاتنين بصراحة بيغيروا شكل الكود…
من كود مكركب…
لكود راقي، منظم، سهل تتغير فيه أي حاجة بعدين ✨



يعني إيه Unit of Work ببساطة؟​

فكر فيها كده…

إنت عندك شغل كتير هيتعمل في الداتابيز:
إضافة Order → تعديل Product → تسجيل Payment

Unit of Work بيجمع العمليات دي كلها في Transaction واحدة.
يعني:
  • يا كله ينجح ✅
  • يا كله يتلغى ❌
مفيش حاجة اسمها نص عملية حصلت ونصها لأ.

زي ما بنقول في الكورة:
يا goal… يا بلّاها 😄



مثال بسيط يوضح الفكرة​

بدون Unit of Work:
C#:
var order = new Order { UserId = 1, Total = 500 };
context.Orders.Add(order);
context.SaveChanges();

var product = context.Products.First(p => p.Id == order.ProductId);
product.Stock -= 1;
context.SaveChanges();

// حصل Error هنا؟ الداتا اتباظت.
كده إحنا بنعمل SaveChanges في كل خطوة.
وده خطر جدًا.

مع Unit of Work بقى:
C#:
unitOfWork.Orders.Add(order);
unitOfWork.Products.UpdateStock(order.ProductId, -1);

unitOfWork.Complete(); // هنا كل حاجة تتنفذ مع بعض
لو أي خطوة ضربت؟
Rollback يرجع كل شيء زي ما كان ✨



طب وإيه بقى حكاية Repository Pattern؟​

شوف… لما تيجي تتعامل مع الداتابيز مباشرة في كل مكان في المشروع:
C#:
context.Users.Add();
context.Orders.Where();
context.Products.First();
إنت كده بتربط الكود كله بـ Entity Framework وربطه بالداتابيز نفسها.

يعني:
  • لو غيرت ORM → عندك مصيبة 😅
  • لو عايز تختبر الكود بدون داتابيز → مستحيل تقريبًا

الـ Repository بقى بيعمل طبقة وسيطة…
بيخلي الكود بتاعك يتعامل مع:
C#:
IUserRepository
IOrderRepository
IProductRepository
مش مع DbContext مباشرة.

بالتالي:
  • الكود بقى واضح
  • سهل الاختبار
  • سهل التعديل
  • Decoupled جدًا



شكل Repository في C#​

C#:
public interface IOrderRepository
{
    Order GetById(int id);
    void Add(Order order);
}

public class OrderRepository : IOrderRepository
{
    private readonly AppDbContext _context;
    public OrderRepository(AppDbContext context)
    {
        _context = context;
    }

    public Order GetById(int id) => _context.Orders.Find(id);

    public void Add(Order order) => _context.Orders.Add(order);
}



طب إزاي نجمعهم مع بعض؟ (الجمال كله هنا 😍)​

C#:
public interface IUnitOfWork : IDisposable
{
    IOrderRepository Orders { get; }
    IProductRepository Products { get; }
    IPaymentRepository Payments { get; }
    int Complete();
}

public class UnitOfWork : IUnitOfWork
{
    private readonly AppDbContext _context;
    
    public IOrderRepository Orders { get; }
    public IProductRepository Products { get; }
    public IPaymentRepository Payments { get; }

    public UnitOfWork(AppDbContext context,
                      IOrderRepository orders,
                      IProductRepository products,
                      IPaymentRepository payments)
    {
        _context = context;
        Orders = orders;
        Products = products;
        Payments = payments;
    }

    public int Complete() => _context.SaveChanges();

    public void Dispose() => _context.Dispose();
}



كده السيناريو يبقى جميل جدًا 🔥

C#:
using (var uow = new UnitOfWork(new AppDbContext()))
{
    uow.Orders.Add(order);
    uow.Products.ReduceStock(order.ProductId, 1);
    uow.Payments.Record(order.UserId, order.Total);
    
    uow.Complete();
}
كود نظيف
سهل يتقرى
سهل يتعدل

ومفيش داتا هتباظ تاني 👌



طب سؤال مهم:​

هو مش DbContext نفسه بيعمل كده؟
أيوه… صح ✅
الـ DbContext في EF Core يعتبر Unit of Work
والـ DbSet يعتبر Repository

لكن…

لو استخدمتهم مباشرة في الـ business logic:
إنت بتربط كل حاجة بالـ Entity Framework.

وده بيخليك مش عارف تختبر الكود بسهولة.

الـ Repository + Unit of Work مش مجرد تكرار…
هو Abstraction Layer
طبقة بتحمي الكود من التعقيد والتغيير.



الخلاصة 🎯

قبلبعد
كود مكركب بيتعامل مع الداتابيز في كل مكانكود منظم بيتعامل بـ Repositories
عمليات ممكن تبوظ الداتا بسهولةTransaction واحدة تحميك
كود صعب يتعدلكود سهل التطوير والتحديث
مستحيل تعمله Unit Testسهل جدًا يتختبر
 
المواضيع ذات الصلة
x32x01
الردود
0
المشاهدات
650
x32x01
x32x01
x32x01
الردود
0
المشاهدات
107
x32x01
x32x01
x32x01
الردود
0
المشاهدات
56
x32x01
x32x01
x32x01
الردود
0
المشاهدات
7
x32x01
x32x01
x32x01
الردود
0
المشاهدات
635
x32x01
x32x01
x32x01
الردود
0
المشاهدات
932
x32x01
x32x01
x32x01
الردود
0
المشاهدات
246
x32x01
x32x01
x32x01
الردود
0
المشاهدات
54
x32x01
x32x01
x32x01
الردود
0
المشاهدات
60
x32x01
x32x01
x32x01
الردود
0
المشاهدات
617
x32x01
x32x01
الدخول أو التسجيل السريع
نسيت كلمة مرورك؟
إحصائيات المنتدى
المواضيع
1,983
المشاركات
2,183
أعضاء أكتب كود
479
أخر عضو
as6318380@gmail
عودة
أعلى