使用Factory with DryIoc并逐个获取对象

时间:2018-02-17 00:34:41

标签: vb.net 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)

出了什么问题,我做错了什么?

还有一件事:这些线之间的差异是什么? (刚看到这个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

1 个答案:

答案 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();

我们假设IFtpISftp都实现了IProtocol。 有两种方法可以指定IFtp依赖IProtocol(不使用服务密钥)。

第一个选项,当您注册依赖性使用者/持有者时:

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

第二个选项,为每个容器指定全局,这将影响IProtocol类型的所有依赖项。

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