C# 依赖注入:我不&x27;我不知道从哪里开始!
我有几篇关于依赖注入的文章,我可以看到它的好处,特别是在单元测试方面。这些单元可以松散耦合,并且可以模拟依赖关系 问题是——我就是不知道从哪里开始 考虑下面这段代码片段(为了本文的目的进行了大量编辑)。我正在从主窗体实例化一个Plc对象,并通过Connect方法以通信模式进行传递 以目前的形式,它变得很难测试,因为我无法将Plc与CommsChannel隔离开来进行单元测试。(我可以吗?) 该类依赖于使用CommsChannel对象,但我只传递用于在Plc本身中创建此通道的模式。要使用依赖注入,我应该将已经创建的CommsChannel(可能通过“ICommsChannel”接口)传递给Connect方法,或者通过Plc构造函数。是这样吗 但这意味着首先在我的主窗体中创建CommsChannel,这似乎也不正确,因为感觉一切都会回到主窗体的底层,一切都从那里开始。不知何故,我觉得我错过了拼图的一个关键部分 你从哪里开始?你必须在某处创建一个实例,但我很难理解它应该在哪里C# 依赖注入:我不&x27;我不知道从哪里开始!,c#,winforms,design-patterns,dependency-injection,C#,Winforms,Design Patterns,Dependency Injection,我有几篇关于依赖注入的文章,我可以看到它的好处,特别是在单元测试方面。这些单元可以松散耦合,并且可以模拟依赖关系 问题是——我就是不知道从哪里开始 考虑下面这段代码片段(为了本文的目的进行了大量编辑)。我正在从主窗体实例化一个Plc对象,并通过Connect方法以通信模式进行传递 以目前的形式,它变得很难测试,因为我无法将Plc与CommsChannel隔离开来进行单元测试。(我可以吗?) 该类依赖于使用CommsChannel对象,但我只传递用于在Plc本身中创建此通道的模式。要使用依赖注入,
public class Plc()
{
public bool Connect(CommsMode commsMode)
{
bool success = false;
// Create new comms channel.
this._commsChannel = this.GetCommsChannel(commsMode);
// Attempt connection
success = this._commsChannel.Connect();
return this._connected;
}
private CommsChannel GetCommsChannel(CommsMode mode)
{
CommsChannel channel;
switch (mode)
{
case CommsMode.RS232:
channel = new SerialCommsChannel(
SerialCommsSettings.Default.ComPort,
SerialCommsSettings.Default.BaudRate,
SerialCommsSettings.Default.DataBits,
SerialCommsSettings.Default.Parity,
SerialCommsSettings.Default.StopBits);
break;
case CommsMode.Tcp:
channel = new TcpCommsChannel(
TCPCommsSettings.Default.IP_Address,
TCPCommsSettings.Default.Port);
break;
default:
// Throw unknown comms channel exception.
}
return channel;
}
}
很难回答这样一个广泛的问题,但是您关于在哪里/谁创建连接对象的具体问题更简单 您可以传入一个factory对象,该对象知道如何创建连接对象以及或代替模式。这样,如果您想创建不同的(例如,mock)连接,您只需传入一个不同的工厂对象,当要求创建一个连接时,该工厂对象会创建一个不同的连接实现 这有帮助吗,还是我错过了真正的问题?我会怎么做 依赖注入是应用S.O.L.I.D原则时迟早会遇到的问题,因此,与其直接投入行动,不如花点时间阅读这篇优秀的pdf 然后结帐 例如
这是我一生中最棒的一次旅行,希望这对你来说也是一次同样激动人心的经历。相关:你是否阅读了“编写应用程序的位置”上的依赖项注入标签简介/常见问题解答:@Mark:我没有看到那个常见问题解答,谢谢。谢谢,这确实有帮助。好的,那么一个CommsChannelFactory。。。你的意思是说有一个使用ICommsChannelFactory接口的工厂,然后在单元测试时用这个接口创建一个MockCommsChannelFactory,然后返回一个伪ICommsChannel对象?(我说的对吗?!)我觉得这是对的。归根结底,一个对象/实现的可插拔性如何,但要保持一定的平衡,否则最终会导致接口和注入的指数级增长,我发现这会导致难以理解的系统。“难以理解”我不需要:)这个例子似乎是一个自然的界面分离关注点的地方,使测试更容易,但我接受你的观点。我们正在讨论的工厂示例是一个完美的界面。令人担忧的是,如果人们做得太多而没有真正的价值,那么你最终会得到大量的小类,这会使系统难以理解,除非你完全理解设计者的心智模型。因此,我的建议是,当你意识到你应该有更多的注入,而不是不断地将其分散到任何地方时,使用好的工具并无情地进行重构。我决定进行重构,将ICommsChannel实例传递给独立工厂生产的Plc。这将至少允许我使用一些模拟通道对Plc进行单元测试。我会接受你的回答,因为这让我想到了这些,谢谢。