【发布时间】:2014-06-14 03:42:24
【问题描述】:
我正在使用 EF6 开发 C# MVC5 项目。目前,上下文是在 UnityConfig.cs 类中创建的,该类是从 Global 中的 Application_Start() 调用的。请看下面的一些使用 UnityConfig 类:
public static void RegisterComponents()
{
var container = new UnityContainer();
BlogSite.Domain.BlogSiteModelContainer context = new Domain.BlogSiteModelContainer();
container.RegisterType<IBlogRepository, BlogRepository>(new InjectionConstructor(context));
}
这样做的问题是数据库可能会直接更新,因此 EF 上下文会变得不一致。所以我需要更改它,以便在每次有新的 http 请求时重新加载它。
我发现 PerRequestLifetimeManager 可能是解决这个问题的方法,但是我找不到一个很好的例子来说明我应该如何使用它。
我应该如何实现这个?还是有更好的办法?
所以我尝试了一些事情,但仍然没有成功。我意识到我可以使用 container.RegisterType() 方法添加生命周期管理器,但我认为这只适用于存储库而不适用于实体框架上下文。
例如
container.RegisterType<IBlogRepository, BlogRepository>(new PerRequestLifetimeManager(), new InjectionConstructor(context));
我仍然不确定如何设置上下文的生命周期。我意识到我可能需要重新格式化代码,但我在任何地方都找不到这种情况的示例。
我一直在做更多的研究,并研究了创建一个工作单元以在其中创建上下文并将其传递给存储库的想法。不确定这是否是最好的前进方式,但它似乎是一种可行的方式。对此有什么想法吗?
【问题讨论】:
-
您的 dbcontext 不仅会变得陈旧,而且会膨胀,因为它缓存了越来越多来自先前交互的垃圾。它并不意味着长寿。通常,我会尝试通过在所需范围内使用
using语句内联来将上下文的生命周期保持在绝对最小值。不过,我不知道这将如何与您的 DI 一起使用。 -
上述方法或类似方法需要以一种可以通过每个请求调用的方式公开,例如 ReRegisterComponents()。但是,这种方式否定了di的一些优点。
-
你不能在你的控制器基类中实例化你的上下文吗?如果不进行过度设计,这难道不能解决您的问题吗?
-
我应该提一下,我的单元测试仍然需要模拟存储库。
-
你的问题是你在你的 DI 框架之外更新你的上下文,所以它总是注入同一个实例。你需要配置你的 DI 来实例化你的上下文。
标签: c# dependency-injection unity-container asp.net-mvc-5 entity-framework-6