【问题标题】:Appropriate Repository LifeCycle Scope w/ Ninject in MVC在 MVC 中使用 Ninject 的适当存储库生命周期范围
【发布时间】:2011-03-10 22:45:59
【问题描述】:

在 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);
   }
 }

忍者模块:

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

我的仓库:

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

}

【问题讨论】:

标签: asp.net-mvc inversion-of-control ninject


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

    这取决于几个因素。

    1. 您是否关心交易?并不是说瞬态范围适合你。

    2. 您是否关心事务,但认为每个 Web 请求一个事务对您来说可以吗?然后使用 web scoped。

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

    【讨论】:

    • 所以你说不能在瞬态范围内进行交易/uow?
    • @B Z - 不,你可以,但在瞬态范围内,你不能为每个 webrequest 或存储库或类似的东西做任何事务。
    猜你喜欢
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多