【问题标题】:How to implement DI using DbContext in Windows Form如何在 Windows 窗体中使用 DbContext 实现 DI
【发布时间】:2011-10-05 07:48:25
【问题描述】:

我有一个在使用 EF Code First 的 winforms 应用程序中运行的类。 DbContext 是通过类构造函数通过 DI 创建的。一切正常。

问题是被引用的数据也正在通过网站进行修改,使用与 EF Code First 相同的 DI 模式,并且数据更改没有反映在 winforms 应用程序的上下文实例中。

我可以通过每次访问它时在 winforms 中重新创建 DbContext 对象来解决这个问题,但对我来说似乎更像是一种服务位置模式?

是否有真正的 DI 技术来实现这一目标? 还是应该从 DI 中删除上下文并使用服务位置?

【问题讨论】:

    标签: winforms dependency-injection ef-code-first


    【解决方案1】:

    您对建议使用的其他问题 (http://stackoverflow.com/questions/7657643/how-to-force-ef-code-first-to-query-the-database) 的答案不满意吗分离、AsNoTracking 还是覆盖更改?

    1) 也许您可以传递一个能够创建 DbContext 的接口,而不是上下文本身。

    using(var context = _contextFactory.Create()) {
      var entity = from table in  context.Blah...;
    }
    

    Create 方法既可以创建具体类本身(稍微击败 DI 模式),也可以使用服务位置为其创建一个。不是很好,但它比在任何地方嵌入服务位置调用要好,而且仍然意味着您可以自己控制生命周期。

    2) 将 WinForm 更改为从网站运行的 Web 服务读取,实际上类似于禁用缓存。

    3) 在 MVC 的核心深处(实际上并没有那么深),它直接引用 DI 容器并将其用作服务定位器以作为新创建对象的参数传递。从技术上讲,您可以在 WinForms 中执行类似的操作,但它需要您将应用程序拆分为生命周期不长的小块(控制器)。也许值得看看一些用于 WinForms 的 MVC/MVP 框架,尽管我发现自己在快速 google 后看到的最多。

    【讨论】:

    • 我以为我遇到了一个单独的问题,但我认为我只是将问题移得更深了。我采用了@Betty 在 1) 中建议的方法,尽管当单独的函数需要开始引用有关更改跟踪的上下文时,我将不得不小心行事。
    • 1) 中建议的工厂应该每次都创建一个新的上下文,而不是重复使用它。
    【解决方案2】:

    问题是被引用的数据也正在通过网站进行修改,使用与 EF Code First 相同的 DI 模式,并且数据更改没有反映在 winforms 应用程序的上下文实例中。

    这与您的期望有问题。

    如果您的 Web 服务和窗口窗体应用程序位于不同的进程中,它们将不会共享内存中的数据。

    如果您想同步他们的内存数据,只需在另一个上下文中提交到数据库 后重新查询即可。这与尝试在不同 SQL 连接之间共享数据相同。

    我可以通过每次访问它时在 winforms 中重新创建 DbContext 对象来解决这个问题,但对我来说似乎更像是一种服务位置模式?

    如果您想重复地重新创建DbContext,您可以使用抽象工厂来允许手动重新创建对象,同时允许您将具体实现注入工厂。

    这不是(必然)服务定位器模式,您必须确保手动处置您的 DbContext 实例。我会给你一些示例代码,但是不同的 DI 容器实现工厂模式的方式完全不同。

    或者您可以简单地确保在 Web 服务端提交数据,然后在 WinForms 应用端重新查询数据。

    【讨论】:

    • 我希望有一个设置可以强制 DbContext 不在内存中存储数据。
    猜你喜欢
    • 2011-06-23
    • 2010-10-13
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2019-03-07
    相关资源
    最近更新 更多