簡體   English   中英

如何防止工作單元抽象泄漏

[英]How to keep Unit of Work abstraction from leaking

我正在學習良好的設計規范,並介紹了工作單元設計模式以及存儲庫。 這使我可以使應用程序邏輯不了解持久性細節,但是在處理某些極端情況時我遇到了一些困難。

首先,在IUnitOfWork接口背后,我使用的是一種使用EF訪問我的數據的實現。 對於我的查詢,我使用“規范”設計模式來創建客戶端可以使用的查詢對象。

因此,到目前為止,事情幾乎都是從數據源中抽象出來的,但這是要解決的:想象一下我想使用AsNoTracking選項檢索一些數據。 我應該如何告訴我的IUnitOfWork實現我不需要跟蹤結果對象?

而且,EF並不真正支持批處理CUD,也不支持Future Queries,但是有一個擴展支持。 我如何以客戶端代碼完全不了解對象持久化的方式來支持這一點? 我可能想要使用平面文件來進行所有代碼維護。

TL; DR; 如何防止UnitOfWork抽象泄漏到客戶端? 有人處理過嗎?

其中大多數將通過注入一個存儲庫來實現,該存儲庫的實現會發出那些未跟蹤的對象,或者將對平面文件的讀/寫對話。

概念性存儲庫所做的很多事情與UoW都是互用的。 回購實現最終有很多這些:

public class MyRepository : IWhateverRepository
{
    // ...
    public Customer GetCustomerByName(string customerName)
    {
        using (var db = new MyContext())
        {
            var customer = db.Customers.Where(cust => cust.Name == customerName).SingleOrDefault();
            return customer;
        }
    }

    public Customer StoreCustomer(Customer customer)
    {
        using (var db = new MyContext())
        {
            db.Entry(customer).State = customer.ID == 0 ? EntityState.Added : EntityState.Modified;
            db.SaveChanges();
        }
    }
}

如您所見,UoW的使用並不多。 我認為使用存儲庫時EF的大部分有用之處在於不必手動編寫SQL。

但是,當沒有存儲庫抽象並且業務邏輯直接與實體和上下文一起工作時,UoW會很好地工作。 例如,在UI <-> MVC <->服務層方案中,您可能讓MVC控制器指示服務層創建新發票:

IMyService svc = new MyServiceLayer();
IInvoice invoice = svc.CreateInvoiceForCustomer(customer, items, paymentInfo);
InvoiceViewModel invoiceVm = Map(invoice);
return RedirectToAction("Display", "Invoice", invoiceVm);

您可以想象服務層可以執行以下操作:

public ServiceResponse<Invoice> CreateInvoiceForCustomer(Customer customer, IEnumerable<InvoiceItem> items, PaymentInfo paymentInfo)
{
    using (var db = new MyContext())
    {
        db.Entry(customer).State = customer.ID == 0 : EntityState.Added : EntityState.Modified;

        var invoice = new Invoice
            {
                Customer = customer,
                InvoiceDate = _timeService.Now(),
                PaymentInfo = paymentInfo
            };
        foreach (var item in items)
            invoice.Items.Add(items);

        db.Invoices.Add(invoice);
        db.SaveChanges();

        return new SeviceResponse<Invoice> 
            {
                IsSuccess = true,
                Data = invoice
            };
    }

}

在此示例中,UoW模式充當事務的替代品。 您會獲得原子性而不會弄臟您的手。

UoW的真正功能是在有狀態的系統(例如WPF)中,在該系統中,您可能擁有一個長期存在的上下文,該上下文用於處理在不同線程上異步執行的大量命令隊列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM