我应该将我的EF DBContext对象保留在自己的模块中,然后通过DI获取它吗?

时间:2017-09-28 20:35:44

标签: c# entity-framework mvvm dependency-injection prism

我目前正在处理从SQL服务器到我的C#WPF应用程序的数据。我正在使用prism和Entity Framework来获取我的DBContext(如果重要的话,使用数据库优先生成)。我有一个不断发展的项目,我将通过不同项目的许多不同屏幕同时连接到此服务器。

最初,我只是为每个ViewModel创建了一个新的DBContext对象,但我有一种感觉,通过在线阅读关于不知道彼此更改的不同上下文实例,这是不正确的。

现在,我正在使用DI将这个相同DBContext的静态实例引入到任何屏幕的ViewModel中,该ViewModel在其构造函数中请求它的接口。我认为这是一个非常简单的改变,但我不知道我是否可以肯定地说这样做更好。

通过下面的示例,这是一种可接受的方法来共享由Entity Framework生成的公共DBContext对象吗?如果没有,我该如何改变或更好?谢谢!

public interface ICommonContext
{
    ServerEntities Context { get; }
}

public class CommonContext : IModule, ICommonContext
{
  private static ServerEntities _context;
  public ServerEntities Context
  {
    get {  return _context; }
  }

  public void Initialize() {  _context = new ServerEntities(); }
}

/// When used in a VM ///
private ServerEntities _model;

public SomeViewModel(ICommonContext cc){
  _model = cc.Context;
}
//////////////////////////

2 个答案:

答案 0 :(得分:2)

基本上我们的工作。我实际上有一段PAIN处理EF(更多的是TFS和分支),主要是因为我们有不同的区域有不同版本的数据库。因此,EF模型基本上可以在每个版本中进行更改。使用DI,您可以传入任何实现您定义的接口的类。如果您决定编写测试用例等,这将非常有用。

长话短说,DI绝对是要走的路。我甚至更进一步,将DbContext与表单分离,并使用类似于您注入表单的存储库。这样,您的表单永远不必知道您的DbContext或数据来自何处。如果您的项目变得更大,或者您有多个来源,或者例如如果您决定废弃EF并做其他事情等,这将有所帮助。

关于使用静态上下文,请参阅Gert的回答。他提出了一个有效的观点。我的答案是为DI建立一个案例。沿着静态上下文路线肯定要谨慎。 Check this article.

答案 1 :(得分:2)

使用静态上下文是邪恶的。不要这样做。

但是在像WPF这样的富客户端应用程序中,每个窗口实例都有一个上下文,它可以归结为每个视图模型的实例。因此,只需在实例生命周期的DI容器中注册上下文,然后通过构造函数注入将其注入到视图模型中。

这意味着:删除您的课程CommonContext