运行时导入可能吗?

时间:2013-09-10 07:43:37

标签: vb.net

我会尽可能清楚地解释问题。我不确定我的需求是否可能,但我希望必须有一些解决方案。我不能在这里输入实际代码,但会添加解释问题所需的一切。

最初我们有两个不同的类,如下所示。

Imports QMember48

Public Class Member48

 Public Function ProcessInfo(reqctx as Member48.RequestContext, memid as String)
 'Code here
 End Function

 Public Function UpdateInfo(partner as Member48.Partner, memid as String)
 'Code here
 End Function

 'Other methods and functions come here

End Class

Imports QMember50

Public Class Member50

 Public Function ProcessInfo(reqctx as Member50.RequestContext, memid as String)
 'Code here
 End Function

 Public Function UpdateInfo(partner as Member50.Partner, memid as String)
 'Code here
 End Function

 'Other methods and functions come here

End Class

基本上这两个类有共同的方法和功能,但引用不同。

我们接下来决定创建一个工厂模式,以根据一些输入参数获取这些类的对象。

我们当前的代码实现是这样的:

'Base class definition
Imports QMember48

Public MustInherit Class Member
 Public MustOverride Function ProcessInfo(reqctx as Member48.RequestContext, memid as String)
 Public MustOverride Function UpdateInfo(partner as Member48.Partner, memid as String)
End Class

'Factory
Public Module MemFactory

 Function GetMember(val as string) as Member
  'Do some processing here
  If val = "500" return new Member50() else return new Member48()
 End Function

End Module

问题是基类引用了Member48,当工厂为Member50生成对象时,对Member48的引用仍然存在。这需要在基类中以某种方式进行纠正。如果需要Member50的对象,则不应该提及Member48。但是,我们如何在没有任何硬编码导入Member48 / 50的情况下定义基类?

有什么办法可以解决这个问题吗?如果需要更多细节,我可以稍后再添加。

感谢。

2 个答案:

答案 0 :(得分:0)

问题是两个Members都没有任何共同的方法。可能有两个具有相同名称的方法,但这些方法具有不同的签名。您既不能将Member48.RequestContext传递给Member50,也不能将Member50.RequestContext传递给Member48。这就是继承不能在这里合理应用的原因。两个成员的共同基类都是空的。

您可以使用通用基类,如下所示:

MustInherit Class Member(Of TRequest, TPartner)
    Public MustOverride Function ProcessInfo(reqctx As TRequest, memid As String)
    Public MustOverride Function UpdateInfo(partner As TPartner, memid As String)
End Class

Class Member48
    Inherits Member(Of QMember48.RequestContext, QMember48.Partner)
    '...
End Class

Class Member50
    Inherits Member(Of QMember50.RequestContext, QMember50.Partner)
    '...
End Class

但是,这个基类对工厂没有任何好处。工厂必须返回一个无类型的Member,你将失去通用实现的任何优势。

另一种方法是尝试统一RequestContextsPartners。如果成员只依赖于普通成员,那么可以通过界面轻松完成。如果没有通用成员,您甚至可以使用空接口(作为所请求类型的提示)并执行以下操作:

MustInherit Class Member
    Public MustOverride Function ProcessInfo(reqctx As IRequestContext, memid As String)
    '...
End Class

具体的Member将负责检查正确的类型,并且如果传递了错误的类型,则可能抛出异常。

最后一种方法是不使用任何基类,让工厂返回Object(或者可能是空基类)。这可能是最干净的解决方案,因为它没有引入任何人工继承。当然,每次访问对象时都必须进行类型检查,但这与大多数其他方法相同。

最后,对你的问题没有一个很好的解决方案。也许你可以修改你的架构,看看是否有更智能的结构,或者你是否真的需要上面列出的Members

答案 1 :(得分:0)

RequestContextPartner创建基类或接口,让Member48.RequestContext / Member50.RequestContextMember48.Partner / Member50.Partner实现这些接口:

Public Interface IRequestContext
End Interface

Public Interface IPartner
End Interface

Class Member48RequestContext
    Implements IRequestContext
End Class

Class Member48Partner
    Implements IPartner
End Class

Class Member50RequestContext
    Implements IRequestContext
End Class

Class Member50Partner
    Implements IPartner
End Class

现在您可以创建一个接受IRequestContestIPartner的基类:

Public MustInherit Class Member
    Public MustOverride Function ProcessInfo(reqctx as IRequestContext, memid as String)
    Public MustOverride Function UpdateInfo(partner as IPartner, memid as String)
End Class

并且具体成员类的实现看起来像

Public Class Member50
    Inherits Member

    Public Overrides Function ProcessInfo(reqctx as IRequestContext, memid as String)
    End Function

    Public Overrides Function UpdateInfo(partner as IPartner, memid as String)
    End Function

End Class

如果需要,还可以使用泛型创建另一个子类:

Public MustInherit Class Member(Of TRequest As IRequestContext, TPartner As IPartner) 
    Inherits Member

    Public Overrides Function ProcessInfo(reqctx as IRequestContext, memid as String)
        Return ProcessInfo(DirectCast(reqctx, TRequest), memid)
    End Function

    Public Overrides Function UpdateInfo(partner as IPartner, memid as String)
        Return UpdateInfo(DirectCast(partner, TPartner), memid)
    End Function

    Public Overloads MustOverride Function ProcessInfo(reqctx as TRequest, memid as String)
    Public Overloads MustOverride Function UpdateInfo(partner as TPartner, memid as String)
End Class

和实施:

Public Class Member48
    Inherits Member(Of Member48RequestContext, Member48Partner) 

    Public Overrides Function ProcessInfo(reqctx as Member48RequestContext, memid as String)
    End Function

    Public Overrides Function UpdateInfo(partner as Member48Partner, memid as String)
    End Function

End Class

请注意Member48仅接受Member48RequestContext,而不是IRequestContext之类的任何Member50。如果您想要这种额外的安全性,这取决于您。

您的工厂方法保持不变:

Function GetMember(val as string) as Member
    'Do some processing here
    If val = "500" Then
        Return New Member50()
    Else 
        Return New Member48()
    End If      
End Function

但是,您的工厂仍然需要 {/ em> Member50Member48的引用,因为它会创建具体的类。

另一种方法是使用像StructureMap这样的DI容器,它能够自动扫描所有实现Member(Of TRequest As IRequestContext, TPartner As IPartner)的所有类型的程序集,为每个程序集分配一个密钥,并返回正确的例如,例如如果要求提供指定密钥,请Member50,例如500.但是,这种配置的完整例子将超出这个问题/答案的范围。