【发布时间】:2014-07-10 17:48:27
【问题描述】:
我有一个相当标准的 MVC 5 应用程序,它由存储库层、服务层和控制器层组成。为了保持每一层的解耦和可测试性,我使用 Ninject 进行依赖注入。
为了重温新技能,我决定使用新的 Task 控制器动作和异步 / 等待服务和控制器方法的 IO 绑定操作。
通常我只是像这样使用 InRequestScope 绑定
kernel.Bind<IDbContext>().To<BlogContext>().InRequestScope();
总的来说,现在这工作正常,但是如果我选择调试我的应用程序,或者将多个跟踪的实体框架对象连接在一起并保存,我会发现上下文已被处理或者我遇到了跟踪问题。我明白为什么会发生这种情况,这是完全合乎逻辑的,因为操作不再发生在 IIS 线程上,所以 Ninject 怎么知道它应该使用相同的上下文。
为了解决这个问题,我可以将我的上下文从我的服务层传递到每个存储库调用,如果需要的话,甚至可以从控制器层向下传递。但是我觉得这看起来很乱,如果可能的话,我宁愿 Ninject 管理这个对象的上下文。
在保持我的代码类似于下面给出的示例的同时以优雅/简约的方式处理此问题的最佳策略是什么?
这是我的控制器方法之一的示例
public virtual async Task<ActionResult> Edit(int id)
{
var editViewModel = await BuildDefaultCreateEditViewModel();
var post = await postService.GetNonDeletedPost(id);
...
...
return View(MVC.Admin.Post.Views.CreateEdit, editViewModel);
}
服务方式
public async Task<PostDTO> GetNonDeletedPost(int postId)
{
return (await PostRepostiory.GetPost(postId)).ConvertToDTO();
}
存储库方法
public Task<Post> GetPost(int postId)
{
return QueryableExtensions.SingleOrDefaultAsync(
DbSet.Where(post => post.PostId == postId)
.Include(post => post.PostVersions)
.Include(post => post.Categories)
.Include(post => post.Files));
}
【问题讨论】:
-
你使用 DbContextFactory 吗?我倾向于使用
TransientScope而不是 Request,我从来没有遇到任何问题 -
我实际上希望我可以以类似于使用 InRequestScope 的 DbContextFactory 的方式使用 Ninject。如果我沿着使用 DBContextFacotry 的路线前进,那么我如何知道异步线程属于哪个请求的问题仍然很明显,我该如何否定这一点?至于使用瞬态范围,它将为每个存储库创建一个新的上下文,这对于使用一个的服务很好,但是当我使用多个(外观模式)将对象拼接在一起并且保存将不起作用,因为来自不同存储库的对象将在不同的跟踪下上下文。
-
这就是我使用ninject的方式,通过DbContextFactory,它允许我将上下文注入到TransientScope中的存储库中。 :)
-
对不起,你的这个“postService”字段每个请求依赖使用 Niject 或默认 MVC 的实际情况?
标签: c# asp.net-mvc asp.net-mvc-5 async-await c#-5.0