依赖注入,实体框架

本文关键字:框架 实体 注入 依赖 | 更新日期: 2023-09-27 18:07:20

所以我使用实体框架,并试图重构我的代码使用依赖注入。在我使用DbContext之前,一切都很顺利。这是一个windows窗体应用程序。到目前为止,我有这个:

 public interface ICruiserContext
{
    DbSet<Customer> Customers { get; set; }
    DbSet<Address> Addresses { get; set; }
    DbSet<Order> Orders { get; set; }
    DbSet<Item> Items { get; set; }
    DbSet<SkuMap> SkuMaps { get; set; }
    DbSet<UnitOfMeasure> UnitOfMeasures { get; set; }
    DbSet<RelativeUnit> RelativeUnits { get; set; }
    DbSet<ShippingMethod> ShippingMethods { get; set; }
    DbSet<ShippingMethodMap> ShippingMethodMaps { get; set; }
}

和我有一个需要上下文的控制器(大部分代码被剥离):

   class ShippingMethodMapper : IMapper
{
    private readonly string _shippingMethod;
    private readonly ICruiserContext _context;
    public ShippingMethodMapper(string shippingMethod,  ICruiserContext context)
    {
        _shippingMethod = shippingMethod;
        _context = context;
    }
    public ICollection<string> GetRemoteValues()
    {
        return new List<string>
        {
            _shippingMethod
        };
    }
    public ICollection<string> GetLocalValues()
    {
        throw new NotImplementedException();
    }
     public void Save(string remoteValue, string localValue)
    {
        throw new NotImplementedException();
    }
}

因此,由于您只想在一个事务中使用上下文,因此每次创建此控制器时,都需要创建一个新的上下文,但如果我简单地使用

注入
context = new CruiserContext();

然后创建控制器的代码不再是可测试的,因为它现在对数据库上下文有一个硬依赖,如果上下文改变了,我将不得不编辑创建新实例的每个文件,违反了打开/关闭原则。所以我的想法可能是使用一个简单的工厂,并委托实例化的责任,如果它:

public static class ContextService
{
    public static ICruiserContext GetContext()
    {
        return new CruiserContext();
    }
}

但是由于静态类不能有接口,现在我只能硬依赖于工厂。那么,注入dbContext的最佳方式是什么呢?

使用非静态类

public interface ICruiserContextFactory
{
    ICruiserContext CreateContext();
}

这是处理IDisposable实例时的标准方法。
将工厂接口传递给类也将允许您编写单元测试。

依赖注入,实体框架

你正确地使用了控制反转原理。下一步-使用ioc - container。它的强大的图案将帮助您解决您的注射和测试问题。