首页 文章

使用DBContext和依赖注入的分歧

提问于
浏览
5

在我正在编写的ASP.NET MVC应用程序中,使用依赖注入来管理我的DBContext仍然是一个新手 .

我正试图遵循文章_2355662中概述的方法 . 基本上,这种方法说使用Ninject和依赖注入,并将我的DBContext作为参数添加到我的控制器中的构造函数中 .

此外,我在基本控制器中实现它,或者我的所有控制器类将被派生 .

这是有效的,但我正在努力解决以下问题 .

  • 这种方法要求每个派生的控制器类也实现一个构造函数,该构造函数接受我的控制器基类所需的任何参数 . 这不仅仅是我必须记住添加到任何新派生类的额外输入,但它也意味着如果我更改传递给构造函数的数据,那么我必须修改每个派生控制器类中的构造函数 .

  • 这给了我所有控制器类的DBContext . 但是我的模型中需要DBContext的其他类呢?我是否需要手动将实例传递给DBContext到所有这些类?或者有没有办法为每个类使用DI来获取自己的DBContext副本?

1 回答

  • 6

    此方法要求每个派生的控制器类还实现一个构造函数,该构造函数接受我的控制器基类所需的任何参数 . 这不仅仅是我必须记住添加到任何新派生类的额外输入,但它也意味着如果我更改传递给构造函数的数据,那么我必须修改每个派生控制器类中的构造函数 .

    这是您可以选择将EF用于您的应用程序的方法之一(重型控制器),IMO并不是最干净的方法 . 你正确地注意到了你自己的缺点 .

    如果我们将这种方法与设计原则联系起来,它会破坏单一责任原则,因为控制器需要做的更多(获取或更新数据库),而不仅仅是收集数据并返回带有数据的相应视图 . 如果需要发送电子邮件,控制器会应用它来管理业务规则,控制器也可以这样做 . 您应该有另一层业务/服务类,专门为一组需求而设计,例如: EmailHelper会发送电子邮件 .

    它还会打破Open Close Principle,因为每次更改输入参数时都需要更改构造函数 .

    这为我的所有控制器类提供了一个DBContext . 但是我的模型中需要DBContext的其他类呢?我是否需要手动将实例传递给DBContext到所有这些类?

    就依赖注入而言,其中一个目标是将依赖注入直接需要的地方 . 如果你有一个需要DbContext的模型类,你应该将它注入你的模型类构造函数中(大多数DI框架支持属性注入,但构造函数仍然是最喜欢的方法) .

    使用DI Framework,您将在一个位置配置依赖项(应用程序初始化代码),然后每个需要依赖项的类只在构造函数中接受它 .

    DI容器可以与字典进行比较,其中键是接口,值是熟化对象 . 设置完成后,您可以随时在整个应用程序中使用正确的密钥来询问任何对象 .

    或者有没有办法为每个类使用DI来获取自己的DBContext副本?

    DI框架支持不同的实例化方式,以允许控制实例的生命周期 . 通常,每个请求,每个线程和单例 . 更多信息here . 如果希望每个控制器都获得DbContext的副本,则可以在设置DbContext实例化时使用每个请求配置 .

    Alternate Solution:

    我的大多数MVC应用程序都有一个服务层(一组应用业务规则的类) . 这些类中的每一个都注入了DbContext(不完全是DbContext而是IDataContext) . 控制器注入了他们需要检索或更新数据的服务类 .

    已经抽象了IDataContext背后的DbContext,我可以在我的测试或明天设置存根数据上下文,如果我想从EF切换到NHibernate或更智能的DI框架,我将只需要实现IDataContext并更改依赖关系初始化代码 .

    希望这可以帮助 .

相关问题