将工厂与Dryioc一起使用,并通过字符串获取对象



我只是使用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();

让我们假设IFtpISftp同时实现IProtocol。有两种方法可以指定您需要IFtpIProtocol依赖关系(无需使用服务键(。

第一个选项,当您注册依赖性消费者/持有人时:

 container.Register<ProtocolUser>(
    made: Parameters.Of.Type<IProtocol, IFtp>());

第二个选项,要在每个容器中指定全球,这将影响IProtocol类型的所有依赖性。

var specializedContainer = container.With(
    Parameters.Of.Type<IProtocol, IFtp>());

最新更新