使用DBContext和依赖注入的分歧

 路见不平出手打_418 发布于 2022-12-08 19:42

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

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

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

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

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

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

SBirthare.. 6

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

这是您可以选择将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并更改依赖关系初始化代码.

希望这可以帮助.

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

    这是您可以选择将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并更改依赖关系初始化代码.

    希望这可以帮助.

    2022-12-11 02:11 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有