首页 > 解决方案 > 在 MVVM 中初始化 DbContext 的位置

问题描述

假设我正在申请。对于用户界面,我决定采用 Model-View-ViewModel 模式。UI 将访问一个服务层,该服务层将使用 Entity Framework Core 作为更传统的存储库的替代品(我知道人们对此有不同的感受,但这不是这个问题的重点)。最好将来自 EFCore 的 DbContext 注入到服务中。像这样的东西:

public void SomeUserInterfaceMethod() 
{
    using (var context = new MyContext()) 
    {
        var service = new MyService(context);
        service.PerformSomeAction();
    }
}

现在这根本不是那么糟糕,但我确实有一个问题。using (var context = new MyContext())它将出现在代码中的很多地方,即使是在一个小型应用程序中。如果我想更改上下文以及出于测试目的,这意味着麻烦。

现在我可以用new MyContext()工厂方法 ( MyFactory.GetMyContext()) 替换 ,这样更容易替换。但是,如果我想将上下文更改为测试上下文(使用另一个数据库)怎么办?

是否有一些更聪明的初始化方法MyContext,既可以轻松替换,又可以轻松测试?

标签: c#mvvmentity-framework-core

解决方案


老实说,我认为将工厂方法用于您的目的没有任何问题。

简单替换示例:

public class ClassWithSomeUserInterfaceMethod
{
    private readonly IDataContextsFactory dataContextsFactory;

    public ClassWithSomeUserInterfaceMethod(IDataContextsFactory dataContextsFactory)
    {
        this.dataContextsFactory = dataContextsFactory;
    }

    public void SomeUserInterfaceMethod() 
    {
        using (var context = dataContextsFactory.GetDataContext()) 
        {
            var service = new MyService(context);
            service.PerformSomeAction();
        }
    }
}

您可以传递任何实现IDataContextsFactory接口的类dataContextsFactory

简单的测试示例:

public AnotherDatabaseDataContextFactory : IDataContextsFactory
{
    public IDataContext GetDataContext()
    {
        return new AnotherDataContext();
    }
}

[Test]
public void SomeTest()
{
    var factory = new AnotherDatabaseDataContextFactory();
    var classWithSomeUserInterfaceMethod = new ClassWithSomeUserInterfaceMethod(factory);

    classWithSomeUserInterfaceMethod.SomeUserInterfaceMethod();

    // Assert.That ...
}

希望能帮助到你。


推荐阅读