在ASP.NET MVC中实例化EF4上下文?

Jal*_*lal 2 c# asp.net-mvc entity-framework instantiation

在microsoft asp.net网站上找到了一个教程,它从上下文中创建一个像这样的实例:

        public class HomeController : Controller
        {
            private MoviesDBEntities _db = new MoviesDBEntities(); 

            public ActionResult Index()
            {
                return View(_db.MovieSet.ToList());
            }

            ...
        }
Run Code Online (Sandbox Code Playgroud)

这意味着每次控制器实例化时,上下文也会实例化.但在这里我发现实例化上下文的正确方法是这样的:

        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                using(MoviesDBEntities _db = new MoviesDBEntities()){
                    return View(_db.MovieSet.ToList());
                }
            }
            ...
        }
Run Code Online (Sandbox Code Playgroud)

所以问题是,哪种方式是正确的?还是重要的?

Iai*_*way 6

通常,类不应该负责实例化自己的依赖项.

最好的办法是将依赖项传递给构造函数: -

public class HomeController : Controller
{
  private IMovieRepository _db;
  public HomeController(IMovieRepository db)
  {
    _db = db;
  }

  public ActionResult Index()
  {
    return View(_db.MovieSet.ToList());
  }
}
Run Code Online (Sandbox Code Playgroud)

这称为"依赖注入",它是可取的,因为它减少了样板代码,并且还允许您在运行时提供其他IMovieRepository实现(例如,如果您是单元测试).

ASP.NET MVC有一个钩子允许你这样做(ControllerBuilder),但幸运的是你不需要自己动手,有预先制作的解决方案.我推荐http://ninject.org/,因为它很容易设置.

这样,您的IoC容器(无论是否传递依赖关系)都可以为每个HTTP请求仅实例化一个上下文,并在请求结束时将其处理掉.

查看例如什么是控制反转?

  • 您应该删除_db的字段初始值设定项.值得指出的是,应该在创建上下文/ DI容器的类中进行上下文的处理. (4认同)