依赖注入,实体框架
本文关键字:框架 实体 注入 依赖 | 更新日期: 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。它的强大的图案将帮助您解决您的注射和测试问题。