我的应用程序是围绕"服务"像这样:
public class ProfileService : BaseService {
private CommService _commService;
public ProfileService(CommService commService) {
_commService = commService;
}
public ApiResponseDto GetProfile(string profileUsername) {
using (var db = new appContext()){ db.DoStuff(); }
}
}
我想要做的是将db
实例化推送到BaseService
,但我不想创建一个dbContext
,并且在我不知道的时候会产生这样的费用不需要它。所以我正在考虑做这样的事情:
public class BaseService {
public AppContext _db;
public AppContext db(){
return _db ?? new AppContext();
}
}
然后我的所有方法都将通过db().DoStuff()
访问数据库。
我不喜欢到处括号的想法,但我更喜欢清理服务足迹的想法。
我的问题是 - 如果我创建DbContext
的实例并且不使用它,是否有任何费用?或者对象是否只是实例化以供将来使用?我不想在这里征求意见,因为我知道这是不允许的,但这是朝着保持干燥的正确方向迈出的一步吗?
答案 0 :(得分:4)
DbContext实际上是' unit of work'的实现。模式 - 创建DbContext
后,当您致电DbSet
时,对SaveChanges
所做的所有更改都会一次性保留。
因此,为了正确回答您的问题,您需要回答的进一步问题是:构成您工作单元的更改范围是什么?换句话说 - 需要以原子方式进行哪些更改 - 所有更改都成功,或者全部失败?
实用(如果有这样的示例 - 假设您有一个API端点,它公开允许客户提交订单的操作。控制器使用OrderService提交订单,然后InventoryService更新与中的项目关联的库存如果每个服务都有自己的DbContext,那么OrderService就有可能成功保留订单提交,但InventoryService将无法保持库存更新。
为了解决这个问题,一个常见的模式是创建一个上下文 per-request ,让你的IoC容器创建和处理上下文,并使其可用于按请求注入服务。 This blog post为DbContext管理提供了一些选项,并包含一个配置Ninject来执行此操作的示例。
这意味着你的ctor会是这样的:
public ProfileService(CommService commService, AppContext context) {
_commService = commService;
_context = context;
}
您可以安全地使用上下文,而不必担心它是如何创建的或来自何处。
但是,我对更复杂应用程序的首选方法是在此处记录的优秀开源库:http://mehdi.me/ambient-dbcontext-in-ef6/。每个请求注入DbContext对于更简单的应用程序都可以正常工作,但随着您的应用程序越来越多(例如,每个应用程序多个上下文,多个数据库等),他的IDbContextScopeFactory
提供的更精细的粒度控制是非常宝贵的。
根据您的评论询问您提出的方法的优缺点,我要说一般来说,注入依赖项(包括DbContext)是一种更加灵活和强大的方法,并且仍然可以实现确保目标你的开发人员不必关心dbcontext生命周期管理。
dependency injection的所有实例的优缺点通常都是相同的,而不仅仅是db上下文,但这里有一些在服务中构建上下文的具体问题(即使在基本服务中):
IQueryable
的任何地方吗?如果你是,那么你冒着IQueryable
即使在DbContext超出范围之后也会导致Db命中的风险 - 它可能已被垃圾收集器处理掉而无法使用。从开发的角度来看,我认为没有什么比DI方法更简单了 - 只需在构造函数中指定DbContext,然后让DI容器容器处理其余部分。
如果您在每个请求中使用DbContext,您甚至不必创建或处置上下文,并且您可以确信IQueryables可以在请求调用堆栈中的任何位置解析。
如果使用Mehdi的方法,则必须创建DbContextScope,但如果您要沿着存储库模式路径并且希望显式控制上下文范围,那么该方法更合适。
正如您所看到的,我不太关心构建DbContext时不需要的计算成本(据我所知,它是相当低的成本,直到你实际上使用它来命中数据库),并且更关注允许单元测试和脱离依赖关系的应用程序架构。