简体   繁体   English

依赖注入,实体框架

[英]Dependency Injection, Entity framework

So I am using entity framework and trying to refactor my code to use dependency Injection. 所以我正在使用实体框架,并试图重构我的代码以使用依赖注入。 All was going good until I got to DbContext. 一切顺利,直到我进入了DbContext。 This is a windows forms application. 这是Windows窗体应用程序。 So far I have this: 到目前为止,我有这个:

 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; }
}

and I have a controller that needs the Context(most code was stripped out): 而且我有一个需要Context的控制器(大部分代码被剥离):

   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();
    }
}

So since you only want to use the context for one transaction, every time this controller is created, a new context needs to be created, but if I simply inject using 因此,由于您只想将上下文用于一个事务,因此每次创建此控制器时,都需要创建一个新的上下文,但是如果我只是使用

context = new CruiserContext();

Then the code that is creating the controller is no longer testable as it has a hard dependency on the database context now, and if the context ever changed I would have to edit every file that creates a new instance, violating the Open / Closed principle. 然后,创建控制器的代码不再可测试,因为它现在对数据库上下文有严格的依赖性,如果上下文发生更改,我将不得不编辑每个创建新实例的文件,这违反了“打开/关闭”原则。 So my idea was maybe to use a simply factory, and delegate the instancing responsibility it it : 因此,我的想法也许是使用一个简单的工厂,并为其委派实例性责任:

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

But since static classes can not have interfaces, now I just have hard dependencies on the factory. 但是由于静态类不能具有接口,所以现在我对工厂只有硬性依赖。 So what is the best way to inject dbContext that can be tested and mocked. 那么,注入可被测试和模拟的dbContext的最佳方法是什么。

Use a non-static class with the interface 在接口上使用非静态类

public interface ICruiserContextFactory
{
    ICruiserContext CreateContext();
}

This is a standard aproach when you're working with IDisposable instances. 当您使用IDisposable实例时,这是一种标准方法。
Passing factory interface to your class will also allow you to write unit tests. 将工厂接口传递给您的类也将允许您编写单元测试。

You use Inversion of Control principle right. 您可以使用控制反转原理。 Nex step - using IoC-Containers . Nex步骤-使用IoC容器 It's powerfull pattern will help you to solve your problems with injections and tesing. 它强大的模式将帮助您解决注射和测试问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM