如何将此服务定位器模式转换为真正的dependency injection模式?

我在一分钟前问了一个更普遍的问题: 如何在应用程序中组织DI Framework使用? 我得到的反馈是,我使用的是Service Locator Pattern而不是真正的DI,正如Martin Fowler在这里指出的那样: http : //martinfowler.com/articles/injection.html

实际上,我前几天读了那篇文章,但显然还没有完全掌握它。

所以我要说我有以下代码:

interface ICardReader { string GetInfo(); void SetDebugMode(bool value); void Initialize(string accountToken); void ShowAmount(string amount); void Close(); ICreditCardInfo GetCardInfo(); } public class MagTekIPAD: ICardReader { public ICreditCardInfo GetCardInfo() { var card = GetCardDataFromDevice(); // apparently the following line is wrong? var ccInfo = Inject.New(); ccInfo.Track1 = MakeHex(card.EncTrack1); ccInfo.Track2 = MakeHex(card.EncTrack2); ccInfo.MagSignature = MakeHex(card.EncMP); ccInfo.MagSwipeKeySN = MakeHex(card.KSN); ccInfo.MagSignatureStatus = MakeHex(card.MPSts); ccInfo.MagDeviceSN = ipad.Serial; ccInfo.MSREncryptType = "MAGENSA_V5"; return ccInfo; } // Other implementation details here ... } 

在这个例子中,我可以将dependency injection构造函数 – 我认为这是修复’this’场景的正确方法。

但是如果我真的需要创建一个未知数量的对象(或者是否还有其他正当理由我需要在课堂上动态创建依赖项)呢?

此示例给我的印象是,您尝试使用IoC容器以ICreditCardInfo方式创建数据传输对象ICreditCardInfo。 这些对象不应该像服务那样​​具有任何真正的依赖关系。 创建DTO的正确方法是使用new运算符:

 return new CreditCardInfo( MakeHex(card.EncTrack1), MakeHex(card.EncTrack2), MakeHex(card.EncMP), MakeHex(card.KSN), MakeHex(card.MPSts), ipad.Serial, "MAGENSA_V5"); 

ICreditCardInfo对象的工厂注入到ICreditCardInfo的构造函数中

 public class MagTekIPAD : ICardReader { private readonly Func factory; public MagTekIPAD(Func factory) { this.factory = factory; } public ICreditCardInfo GetCardInfo() { var info = factory(); // ... return info; } } 

如果几个容器知道如何创建T实例,那么它们可以自动生成Func委托,因此您不必定义工厂接口或抽象工厂类。

正如Fowler指出的那样,Service Locator是更直接的方法,并且不易出错。

一些dependency injection框架要求您声明您是在处理Singleton还是它们可以具有不同的生命周期 。