在我正在编写的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并更改依赖关系初始化代码.
希望这可以帮助.
这种方法要求每个派生的控制器类还实现一个构造函数,该构造函数接受我的控制器基类所需的任何参数.这不仅仅是我必须记住添加到任何新派生类的额外输入,但它也意味着如果我更改传递给构造函数的数据,那么我必须修改每个派生控制器类中的构造函数.
这是您可以选择将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并更改依赖关系初始化代码.
希望这可以帮助.