我只是使用Dryioc库测试反转控制。请在上面检查以获取图片。
我有那个工厂课程:
'FactoryConnections using IoC Dry
Public Class FactoryConnections
Private Shared ReadOnly Container As Container
Shared Sub New()
Container = New Container()
With Container
.Register(Of ISftp, Sftp)
.Register(Of ISaop, Soap)
'.Register(Of IFtp, Ftp)
.Register(Of IFtp, Ftp)(serviceKey:= "some string value")
End With
End Sub
Public Shared Function ResolveService(Of T As IProtocol)(value As Iprotocol) As T
Return Container.Resolve(Of T)
End Function
End Class
很快根据反转:
A -> Y (A uses Y)
A -> Interface B -> Y (in this case A doesn't know about Y)
我们可以同样阅读我的解决方案:
A -> IFtp -> Ftp
因此,而不是像以下内容那样直接获得对象:ftp,sftp或soap代码应要求工厂根据接口获取其中一个,因此调用点不确切地知道具体对象正在使用什么,但它知道谁实现了这一点 - 那是在弹药中,我的理解。因此,我可以通过接口打电话给他们。但是,这是我尝试从字符串值(与项目相关的要求(中做的。
Dim myProtocol As String = "IFtp"
,正如提到的那样,我想从工厂获得适当的对象,在这种情况下,我应该获得FTP的新实例吗?
请注意,IFTP,ISOAP,ISFTP的父界面是Iprotocol
我是这样尝试的:
Dim myProtocol As String = "IFtp"
Dim itemprotocol As type = Type.GetType(myProtocol)
Dim realprotocolobject = FactoryConnections.ResolveService(TypeOf(itemprotocol))
也尝试过这样的尝试:
Dim myProtocol As String = "IFtp"
Dim realprotocolobject = FactoryConnections.ResolveService(Of IProtocol)(myProtocol)
怎么了,我在做什么错?
另一件事:这些行之间的差异是什么?(刚看到这个服务键。(
.Register(Of IFtp, Ftp)
.Register(Of IFtp, Ftp)(serviceKey:= "some string value")
进一步的讨论参考:
工厂课程:https://1drv.ms/i/s!vbwpypyoih0iqruvthcndfyom
UnitTestClass:https://1drv.ms/i/s!vbwpypyoih0g7iefy427ajxxw
我不知道如何编写正确的VB,因此请尝试使用C#回答。希望它可以轻松翻译。
您可以在注册和决心中使用serviceKey
来识别许多相同类型的服务,例如IProtocol
。
container.Register<IProtocol, Ftp>(serviceKey: "ftp");
container.Register<IProtocol, Sftp>(serviceKey: "sftp");
以后:
var p = container.Resolve<IProtocol>(serviceKey: "sftp");
Assert.IsInstanceOf<Sftp>(p);
您可以通过ResolveMany
或注入数组或IEnumerable
参数获取所有协议。
var ps = container.ResolveMany<IProtocol>();
Assert.AreEqual(2, ps.Count());
请注意,我没有在ResolveMany
中指定serviceKey
。
注入键控依赖性
可能有一种情况,您希望通过密钥解决深层依赖。然后,在注册依赖性消费者时,您可以这样指定:
container.Register<ProtocolUser>(
made: Parameters.Of.Type<IProtocol>(serviceKey: "ftp"));
var pu = container.Resolve<ProtocolUser>();
Assert.IsInstanceOf<Ftp>(pu.Protocol);
还有其他方法,例如使用必要的ServiceType。
这是示例:
container.Register<IFtp, Ftp();
container.Register<ISftp, Sftp();
让我们假设IFtp
和ISftp
同时实现IProtocol
。有两种方法可以指定您需要IFtp
的IProtocol
依赖关系(无需使用服务键(。
第一个选项,当您注册依赖性消费者/持有人时:
container.Register<ProtocolUser>(
made: Parameters.Of.Type<IProtocol, IFtp>());
第二个选项,要在每个容器中指定全球,这将影响IProtocol
类型的所有依赖性。
var specializedContainer = container.With(
Parameters.Of.Type<IProtocol, IFtp>());