如何将此服务定位器模式转换为真正的依赖注入模式?

时间:2012-02-21 06:09:54

标签: c# .net dependency-injection inversion-of-control ioc-container

我在一分钟前提出了一个更普遍的问题:How to organize DI Framework usage in an application?,我得到的反馈是我正在使用服务定位器模式而不是真正的DI,正如Martin Fowler在此指出:{{3} }

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

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

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<ICreditCardInfo>.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 ...
}

在这个例子中,我可以将依赖注入到构造函数中 - 我认为这是修复'this'场景的正确方法。

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

3 个答案:

答案 0 :(得分:7)

此示例让我觉得您尝试使用IoC容器命名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");

答案 1 :(得分:3)

ICreditCardInfo个对象的工厂注入MagTekIPAD

的构造函数中
public class MagTekIPAD : ICardReader
{
  private readonly Func<ICreditCardInfo> factory;
  public MagTekIPAD(Func<ICreditCardInfo> factory)
  {
    this.factory = factory;
  }
  public ICreditCardInfo GetCardInfo()
  {
    var info = factory();
    // ...
    return info;
  }
}

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

答案 2 :(得分:-1)

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

某些依赖注入框架要求您声明是否正在处理Singleton,或者他们可以使用不同的lifetimes