类,该类支持可注入模拟对象,但也使用语句c#

类,该类支持可注入模拟对象,但也使用语句c#,c#,unit-testing,C#,Unit Testing,如何创建一个类,将所有EF存储库调用封装在Using语句中,同时还支持存储库的可注入接口 我似乎无法让这个类支持两种不同类型的实例化 public class MyClass(IRepo repo) { _repo = repo; } public void MyMethod() { using ( var db = new DbContxt() ) { var repo = new Repo(db); repo.GetById(1);

如何创建一个类,将所有EF存储库调用封装在Using语句中,同时还支持存储库的可注入接口

我似乎无法让这个类支持两种不同类型的实例化

public class MyClass(IRepo repo)
{
    _repo = repo;
}

public void MyMethod()
{
   using ( var db = new DbContxt() )
   {
        var repo = new Repo(db);
        repo.GetById(1);
   }
}

本质上,“db”对象的生命周期就是方法调用的生命周期。而“db”的生存期将在类外管理(如果注入)

你不应该那样做。为您的
Repo
创建一个无参数构造函数,并在那里实例化
DbContext
。您还可以为它设置一个重载,该重载使用
DbContext
,但您不必这样做。关键是让每一层只关心自己需要什么。让IOC容器在创建时注入所有内容,不要在方法中为不同的层创建对象。

您可以这样构造它:

public class MyClass
{
    private readonly IRepo _repo;

    //or if you want a parameterless constructor...
    public MyClass() : this(new Repo()) { }      

    public MyClass(IRepo repo)
    {
        _repo = repo;
    }

    public MyObject MyMethod(int id)
    {
        _repo.GetById(id);
    }
}

public interface IRepo
{
    MyObject GetById(int id);
}

public class Repo : IRepo
{
    public MyObject GetById(int id)
    {
        using ( var db = new DbContext())
        {
            //do your db related stuff here
         }
    }
}
您需要一种将
Repo
的实例注入
MyClass
的方法,因此可以看看IoC


这样,您就可以轻松地模拟
IRepo
进行测试。

我认为您的代码需要重写一点!很容易看出这只是出于澄清目的的伪代码。此外,dbcontext工厂也应该被注入到Repo中。@KirillBestemyanov只是展示了一种方法,而不是一个完整的示例