我在一分钟前提出了一个更普遍的问题: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'场景的正确方法。
但是如果我真的需要创建一个未知数量的对象(或者是否还有其他正当理由我需要在课堂上动态创建依赖项)?
答案 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)