繁体   English   中英

使用DBContext和依赖注入的分歧

[英]Ramifications of using DBContext with Dependency Injection

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

我试图遵循ASP.NET MVC中的管理实体框架DbContext Lifetime一文中概述的方法。 基本上,这种方法说使用Ninject和依赖注入,并将我的DBContext作为参数添加到我的控制器中的构造函数中。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

替代解决方案:

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

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

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM