繁体   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