سؤال

أحاول كتابة بلدي نموذج المجال كما هو الحال في الثبات قدر الإمكان. الشيء الوحيد الذي أفعله الآن هو وضع علامة على كل عقار وطريقة virtual, ، كما يتطلب nhibernate ذلك لتحميل كسول.

في مجموعة نموذج المجال أحدد بعض واجهات المستودعات:

public interface IRepository<TEntity> where TEntity : EntityBase {
    TEntity Get(int id);
    /* ... */
}
public interface IProductRepository : IRepository<Product> { ... }

ثم لدي تجميع البيانات. سيشير هذا إلى nhibernate ، فهو يعرف عن وجوده. هذه هي التجميع التي تنفذ واجهات المستودع هذه:

public abstract class Repository<TEntity> : IRepository<TEntity> {
    public TEntity Get(ind id) { ... }
    /* ... */
}
public class ProductRepository : Repository<Product>, IProductRepository {
    /* ... */
}

وهلم جرا.

الآن أردت ذلك تنفيذ وظيفة المعاملة لمستودعي. للقيام بذلك ، أود أن أضيف BeginTransaction طريقة على واجهة IrePository الخاصة بي. ومع ذلك ، لا يمكنني تحديد نوع العودة كما NHibernate.ITransaction, ، بما أنني أرغب في الحفاظ على نموذج النموذج المتجانس ، وعدم إجبار على الإشارة إلى مجموعة Nhibernate من مجموعة نموذج النطاق الخاصة بي.

ماذا كنت ستفعل؟

هل يمكنك ببساطة تنفيذ ملف void BeginTransaction(), ، أ void Commit(), ، و void RollBack() طرق على الواجهة ، ودع إدارة المستودع إدارة ITransaction اعتراض داخليًا?

أو هل ستجد طريقة ل فضح ITransaction هدف للسماح للعميل بإدارة المعاملة مباشرة معها ، بدلاً من استخدام أساليب المستودع؟

شكرًا!

هل كانت مفيدة؟

المحلول

يمكنك إلقاء نظرة على الهندسة المعمارية الحادة الذي نفذ بالفعل كل ما تتحدث عنه ، بما في ذلك المستودعات العامة مع دعم المعاملات. الحل هناك هو أن iRepository يحتوي على خاصية DBContext التي تغلف المعاملات (إنها في الواقع واجهة). هذا هو أول الخيارات التي وصفتها (واجهة المعاملات المخصصة التي تخفي nhibernate). وهو يعمل بشكل جيد.

أعتقد أنه يمكنك حتى إعادة استخدام رمز ARP#بغض النظر عما إذا كنت تنوي استخدام الإطار الكامل.

نصائح أخرى

يجب أن تبدأ معاملات IMO دائمًا وينتهي في منطق العمل ، وبعبارة أخرى ، يجب أن تبدأ المعاملة في طبقة الخدمة وليس طبقة المستودع ويجب أن يجند المستودع ذاتيًا في المعاملة ، وسيتم ذلك بشكل مثالي.

الآن إذا كنت تستخدم NH ، فإذا شاركت خدمتك ومستودعاتك نفس "الجلسة" (التي يجب عليهم) ، فيمكنك الاتصال بـ "BeginTransaction" في طبقة الخدمة والالتزام أو التراجع كما هو مطلوب:

على سبيل المثال ، تخيل هذه الطريقة في الخدمة:

  public void RegisterCustomer(Customer customer)
    {
        try
        {
            using(var transaction = _session.BeginTransaction())
            {
                _customerRepository.Save(customer);
                _customerSurveyRepository.Save(customerSurvey);
                // DO What ever else you want...
                transaction.Commit();
            }
        }
        catch (Exception exn)
        {
            throw new AMException(FAILED_REGISTRATION, exn);
        }
     }

يمكن حل كيفية الحصول على إشارة إلى الجلسة نفسها عن طريق الحقن في البنائين أو باستخدام SessionFactory للحصول على الجلسة الحالية ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top