在我的MVC控制器中,我使用的是IoC容器(Ninject),但在实体框架ObjectContext中,我不确定如何最好地使用它。
目前,我正在做类似的事情:
using(var context = new MyObjectContext())
{
var stuff = m_repository.GetStuff(context);
}
从最简单的时间保持数据库连接开放的角度来看,这是管理的最佳方式。
如果我是基于每个请求通过Ninject创建ObjectContext,这显然会使数据库连接保持打开状态太长时间。
上面的代码也会变成......
var stuff = m_repository.GetStuff(m_myObjectContext);
(我什么时候处理上下文......?)
我应该为ObjectContext创建一个工厂并通过DI传递它吗?这会松开耦合,但是如果没有简单的方法来维护ObjectContext的接口(我知道的话),这对可测试性有帮助吗?
有更好的方法吗?感谢
答案 0 :(得分:3)
这是保持最佳管理方式的最佳方式 数据库连接在最短的时间内打开。
如果我是按每个请求通过Ninject创建ObjectContext 基础上,这显然会使数据库连接保持打开状态太长时间。
实体框架将在执行每个查询后直接关闭连接(除了从外部提供打开的连接时),因此您执行此类操作的参数不成立。
过去我曾经通过业务逻辑(我的command handlers来确切)控制上下文(创建,提交和处理它),但缺点是你需要传递这个所有其他方法和所有依赖项的上下文。当应用程序逻辑变得更复杂时,这会导致代码的可读性和可维护性降低。
出于这个原因,我转移到了一个模型,在该模型中,工作单元(您的MyObjectContext
)被创建,提交并处置在业务逻辑的控制范围之外。这允许您将工作单元注入所有依赖项,并为所有对象重用相同的工作单元。缺点是,这会使您的DI配置更加困难。您需要确定的一些事项:
DbContext
未处理时可能不是问题,因为欠照连接已关闭且DbContext
确实没有实现终结者。)我可以给你的一个提示是在command handlers周围对系统中的业务逻辑进行建模,因为这允许你定义一个处理事务行为的装饰器(提交工作单元甚至可能运行所有内容)在一个数据库事务中)在一个点上。这个装饰器可以包裹在系统中的每个处理程序中。
我必须承认我不知道如何使用Ninject注册泛型类型和泛型装饰器,但是当你在Stackoverflow上询问时,你可能会很快得到答案。