适当的存储库LifeCycle Scope w/Ninject在MVC中

B Z*_*B Z 4 asp.net-mvc ninject inversion-of-control

在MVC 3应用程序中将Entity Framework 4与Ninject一起使用时,存储库和EF上下文的相应LifeCycle Scope是什么?

我一直在使用默认的InTransientScope,但质疑它是否应该是InRequestScope.

 public class MyController: Controller
 {
   private readonly IMyRepo _repo;
   public MyController(IMyRepo repo)
   {
     _repo = repo;
   }

   public ActionResult Index()
   {
     var results = _repo.GetStuff();
     return View(results);
   }
 }
Run Code Online (Sandbox Code Playgroud)

Ninject模块:

  public class MyServices : NinjectModule
  {
    public overrride void Load()
    {
      Bind<IMyRepo>.To<MyRepo>();
      Bind<MyContext>.ToSelf();
    }
  }
Run Code Online (Sandbox Code Playgroud)

MyRepo:

public class MyRepo: IMyRepo
{
  private readonly MyContext _context;
  public MyRepo(MyContext context)
  {
    _context = context;
  }
  public IEnumerable GetStuff()
  {
    return _context.Entity;//query stuff
  }

}
Run Code Online (Sandbox Code Playgroud)

Vad*_*dim 6

您的存储库可以是临时范围,但是,我会在请求范围中绑定上下文.这样,所有存储库实例都将共享相同的上下文.这样您就可以获得ORM的缓存和事务优势.

它在您的代码中当前的工作方式是在您请求时创建新的上下文.因此,如果您的控制器首先使用存储库,然后调用另一个模块,而该模块又使用存储库.每个存储库都将具有不同的上下文实例.因此,实际上您现在只是将ORM用作连接管理器和SQL生成器.

这也可能产生意想不到的后果.想象一下如下代码:

public ActionResult MyAction(int id)
{
    var entity = _repository.Get<Entity>(id);
    entity.Prop = "Processing";
    _module.DoStuff(id);
}
Run Code Online (Sandbox Code Playgroud)

如果DoStuff方法最终_repository.Get<Entity>(id);再次调用,则您将拥有2个不同的实体副本.