MVC 中带有 Ninject 的适当存储库生命周期范围

发布于 2024-10-21 12:15:58 字数 910 浏览 10 评论 0原文

在 MVC 3 应用程序中将 Entity Framework 4 与 Ninject 结合使用时,存储库和 EF 上下文的适当生命周期范围是什么?

我一直在使用默认的 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);
   }
 }

Ninject 模块:

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

MyRepo:

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

}

What is the appropriate LifeCycle Scope for a repository and the EF context when using Entity Framework 4 with Ninject in an MVC 3 application?

I've been using the default of InTransientScope, but questioning whether it should be 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);
   }
 }

Ninject Module:

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

MyRepo:

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无语# 2024-10-28 12:15:58

您的存储库可以是瞬态范围,但是,我会将上下文绑定在请求范围中。这样,您的所有存储库实例将共享相同的上下文。通过这种方式,您可以获得 ORM 的缓存和事务优势。

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

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

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

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

Your repository can be transient scope, however, I would bind the context in request scope. This way all of your repository instances will share the same context. This way you can reap the caching and transactional benefits of an ORM.

The way it works currently in your code is that a new context is created any time you request one. So if your controller first uses a repository and then calls another module that in turn uses a repository. Each of those repositories will have a different instance of the context. So in effect you are now using your ORM simply as a connection manager and SQL generator.

This can also have unintended consequences. Imagine a code like the following:

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

If the DoStuff method, eventually calls _repository.Get<Entity>(id); again, you will have 2 different copies of your entity that are out of sync.

薯片软お妹 2024-10-28 12:15:58

这取决于几个因素。

  1. 您关心交易吗?瞬态作用域并不适合您。

  2. 您是否关心交易,但认为每个网络请求一笔交易适合您?然后使用 Web 范围。

  3. 您是否同意将对象“缓存”在 EF 上下文中,并且如果您两次请求同一对象,则不希望完全刷新数据库? Web 范围有此副作用。

This depends on a couple of factors.

  1. Do you care about transactions at all? It not that transient scope is ok for you.

  2. Do you care about transactions but think one transaction per web request is ok for you? Then use web scoped.

  3. Are you ok with objects being "cached" in EF's context and don't want a full database refresh if you request the same object twice? Web scope has this side effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文