依赖注入,将“可注入”对象(服务)注入新的(实体)

时间:2012-03-14 11:18:03

标签: dependency-injection extension-methods service-locator injectable newable

编写代码时,我们应该能够识别两大组对象:

  • 注射剂
  • Newables

http://www.loosecouplings.com/2011/01/how-to-write-testable-code-overview.html

http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

  • 可注入对象是在其构造函数中公开依赖项的对象(服务),这些依赖项通常使用IoC容器解析,这些对象只能在其构造函数中请求其他注入项

  • Newable是在其构造函数中也暴露依赖关系的对象,但是newables只能请求其他可新建对象(实体,值对象),新对象的另一个特征是它们不应该持有对可注入对象的引用

但是在编写代码时,我们经常需要将一个服务(可注入)“注入”到一个实体(newable)

我一直在想,在一个新的对象中暴露服务依赖可能更好地在方法级别进行,但这听起来有很多工作要做....只是考虑在每次调用方法时解析依赖关系....好吧,这就好像我们必须使用服务定位器反模式

我解决这个问题的方法是:

  • 使用暴露依赖关系的方法创建一个接口(该方法将使用该服务)

  • 为接口创建扩展方法并将其放在不同的命名空间中,可能放在另一个程序集中,然后将调用包装为使用服务定位器解析依赖关系的原始方法

这样做,我们可以在新的和可注射的对象之间保持一致的分离,并且能够轻松地在我们的新手中使用服务

  • 您怎么看?
  • 在扩展方法中使用服务定位器被认为是一种不好的做法?
  • 您如何对扩展方法调用进行单元测试?

1 个答案:

答案 0 :(得分:3)

  

但是在编写代码时,我们经常需要注入"一项服务   (可注射)到实体(新的)

情况并非如此 - 如果您发现需要这样做,那么实体中应存在一些应该在服务中的功能。

让我们说你的新品是ShoppingCart,你的注射剂是一个数据库repository。您希望能够这样做:

// somehow cart already got the repository
cart.save();

嗯,你做错了。相反,你需要改变现状并做:

respository.save( cart );

如果你能提供你认为有必要这样做的情况,我们可以讨论这种情况的细节。