我只是使用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)
出了什么问题,我做错了什么?
还有一件事:这些线之间的差异是什么? (刚看到这个serviceKey somwhere ..)
.Register(Of IFtp, Ftp)
.Register(Of IFtp, Ftp)(serviceKey:= "some string value")
进一步讨论参考:
工厂类: https://1drv.ms/i/s!AkQvbwpYPYoIh0IqruVthcndFyOM
UnitTestClass: https://1drv.ms/i/s!AkQvbwpYPYoIh0G7iEfy427aJXXw
答案 0 :(得分:0)
我不知道如何编写正确的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());
请注意,我未在serviceKey
中指定ResolveMany
。
可能存在一种情况,您希望通过密钥解决内部依赖性问题。然后,当注册依赖性使用者时,您可以像这样指定它:
container.Register<ProtocolUser>(
made: Parameters.Of.Type<IProtocol>(serviceKey: "ftp"));
var pu = container.Resolve<ProtocolUser>();
Assert.IsInstanceOf<Ftp>(pu.Protocol);
还有其他方法,例如使用requiredServiceType。
以下是示例:
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>());