[英]How to set up DI / IoC and/or Factory pattern design in C#
我有一个需要SSH连接的设计,以便到达命令行界面来运行某些系统/功能级别的测试自动化。 可能有几种不同类型的SSH客户端:
我在使用Visual Studio的C#下使用SSH.NET开源库作为NuGet包,并且在一个简单的连接,发出命令和读回StdOut和StdErr响应的情况下使所有内容工作。
我的问题是,我想在这里实现一些Session / Command层,并且不确定如何正确使用接口来实现它们。 我想使用DI / IoC将SshSession
和SshCommand
层相互分离,并与SSH.NET SshClient
类SshClient
,但是如何开始设计呢?
我已经阅读了很多关于DI / IoC的解释并使用IoC容器等实现了一些单元测试,但设置DI的核心方法仍然没有点击。 我认为我不需要一个IoC容器来实现它,但可能需要使用工厂模式甚至是其他一些我还不熟悉的模式。
例如,要创建多个客户端类型,具有不同的连接标准,我以为我需要类似的东西:
ISshSession
接口 SshSessionBase : ISshSession
作为基类 SshSessionBase
自定义类。 但那么DI实际上是如何运作的呢? 自定义类是否作为IsshSession
对象注入到基类的构造函数中? 或者我是否需要另一个使用这些自定义类对象的工厂或执行程序类?
我可能会在这里混淆主题..我只是缺少将我正在阅读的内容转换为实际实现的内容 - 感谢任何帮助!
我不确定我是否了解您的设计,但一般方法可能如下:
考虑所有客户端连接处理程序共有的行为和结构元素,并提取基类或接口。 例如,可能存在Connect()
或Send(ICommand)
方法。
考虑设计中其他组件的结构和行为元素,例如命令或记录器或其他任何组件。 结果将是某种基类库。
确定如何实例化连接类型的具体实例。 如果关于连接类型的决定依赖于一组参数,则可以使用工厂。 工厂将获取一组参数并返回连接类型实例。 工厂可以自己实现接口,因此可以由IoC本身(抽象工厂)解决。
工厂本身可以实例化具体类,但是您的连接类可以利用基于构造函数的注入来访问其他组件(记录器,帮助器等),因此您的工厂可以依赖IoC容器,例如:
更新 :正如Michael指出的那样,将容器传递到工厂可能很方便,但隐藏了工厂的具体依赖性。 虽然对于较小的应用程序可能没问题,但更好的方法是将所有连接类型依赖项传递给实例化实例的工厂。
class StandardConnectionFactory : IConnectionFactory
{
private readonly IContainer iocContainer;
public StandardConnectionFactory(IContainer iocContainer)
{
this.iocContainer = iocContainer;
}
public IConnection Create(string param1, int param2, ...)
{
if (...) return iocContainer.Resolve<IFancySshConnection>();
else return iocContainer.Resolve<IAnotherConnection>();
}
}
(伪代码)
// Registration Process
containerBuilder.Register<FancySshConnection>().For<IConnection>().WithName("ssh");
containerBuilder.Register<FancyFtpConnection>().For<IConnection>().WitName("ftp");
// Resolve
var connection = container.ResolveByName("ftp")
当您通过显式工厂(3)或某些内置实例化(4)实现实例化连接的方法时,将自动注入IoC容器已知的连接类型的依赖关系。 例如,上面调用iocContainer.Resolve<IFancySshConnection>();
将实例化具体的连接类型,查看其构造函数,尝试解析每个参数,注入它们,等等。 只要找到之前注册的依赖项,它就会爬上依赖树。 所以你基本上所要做的就是注册你的基类组件(2)。
如果事情变得更大,更复杂,你最终可能会注册。 一些IoC容器(我坚持使用Autofac示例因为我非常喜欢Autofac)提供了一种将注册拆分为模块的简便方法。 这允许将注册过程分配到不同的组件中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.