使用UnitOfWork时是否应妥善解决问题?

时间:2019-11-25 16:28:03

标签: c# entity-framework design-patterns unit-of-work

自从我使用实体框架以来,我一直在网上学习有关实体框架的UnitOfWork模式。我对为什么DataContext是公共UnitOfWork构造函数的参数感到困惑。这意味着,如果我在应用程序的另一层中使用UnitOfWork,则另一层必须了解DataContext。这似乎不是很好的关注点分离。我想念什么吗?

UnitOfWork:

 public class UnitOfWork : IUnitOfWork
    {
        private readonly PurchasingDataContext _context;

        public UnitOfWork(PurchasingDataContext context)
        {
            _context = context;
            Items = new ItemRepository(_context);
            Manufacturers = new LabelerRepository(_context);
            Quotes = new QuoteRepository(_context);
            Vendors = new VendorRepository(_context);
            Contacts = new ContactRepository(_context);
        }



        public IItemRepository Items { get; private set; }
        public ILabelerRepository Manufacturers { get; private set; }
        public IQuoteRepository Quotes { get; private set; }
        public IVendorRepository Vendors { get; private set; }
        public IContactRepository Contacts { get; private set; }

        public int Complete()
        {
            return _context.SaveChanges();
        }

        public void Dispose()
        {
            _context.Dispose();
        }
    }

接口:

public interface IUnitOfWork : IDisposable
    {
        IContactRepository Contacts { get; }
        IItemRepository Items { get; }
        ILabelerRepository Manufacturers { get; }
        IQuoteRepository Quotes { get; }
        IVendorRepository Vendors { get; }
        int Complete();
    }

2 个答案:

答案 0 :(得分:1)

  

对于为什么在本教程中DataContextpublic UnitOfWork构造函数的参数,我感到困惑。

这是为了将依赖项注入到UoW中。这样,您可以轻松兑现SRP
借助它,您可以在UoW之外单独管理DataContext的范围。在不同情况下使用相同的UoW(例如Windows应用程序与Web应用程序)时,这为您提供了很大的灵活性。这样,您可以按照自己的方式扩展数据库事务。

  

这意味着如果我在应用程序的另一层中使用UnitOfWork,则另一层必须知道DataContext

是;但并非完全正确。是的,DataContext的实例应该通过调用层进行托管(创建,注入和处置)。而已。该层无需以任​​何方式与此实例进行交互。

  

这似乎不是很好的关注点分离。

为了延续到先前的观点,调用层不需要知道该实例如何工作。所有这些部分都在您的UoW类中进行了抽象。这是明确的关注点分离。

  

我想念什么吗?

希望您现在知道。

答案 1 :(得分:0)

我首先要问您为什么要在UnitOfWork中创建和公开这些存储库。具有负责一个工作单元和所有存储库所有权的单一类违反了“单一责任原则”。您的IUnitOfWork公开了调用者可能需要或不需要的每个单个存储库,这违反了接口隔离原则。

您应该使用依赖项注入框架来代替此方法,以管理上下文,存储库和工作单元的生命周期。框架应确保为每个请求创建一个实例,并在需要时在依赖关系之间共享。

典型的EntityFramework UnitOfWork类似于:

public interface IUnitOfWork
{
    void SaveChanges();
}

具有类似的实现:

public class UnitOfWork : IUnitOfWork
{
    private readonly PurchasingDataContext _context;

    public UnitOfWork(PurchasingDataContext context)
    {
        _context = context;
    }

    public void SaveChanges()
    {
        return _context.SaveChanges();
    }
}