.net - 如何以编程方式(在运行时)向类添加接口(interface)

标签 .net vb.net reflection interface

我正在寻找一种在运行时向类添加接口(interface)实现的方法。 这是一个示例代码,我将在下面讨论。

Public Interface IAction
    Sub DoThis(a As Integer)
End Interface


Class Actor
Implements IAction

    Private mNumber As Integer

    Public Sub New(number As Integer)
        mNumber = number
    End Sub

    Public Sub DoThis(a As Integer) Implements IAction.DoThis
        Console.WriteLine(String.Format("Actor #{0}: {1}", mNumber, a))
    End Sub

End Class


Class ActionDispatcher
Implements IAction

    Private Shared mActionList As New List(Of IAction)

    Public Shared Sub Add(actor As IAction)
        mActionList.Add(actor)
    End Sub

    Public Sub DoThis(a As Integer) Implements IAction.DoThis
        For Each act In mActionList
            act.DoThis(a)
        Next
    End Sub

End Class


Module Module1

    Sub Main()
        Dim a As New ActionDispatcher
        ActionDispatcher.Add(New Actor(1))
        ActionDispatcher.Add(New Actor(2))
        a.DoThis(5)
    End Sub

End Module

这与 WCF 相关,其中需要向 CreateHost 提供一个类,该类实现端点所需的所有接口(interface)。在这个场景中,ActionDispatcher就是这样一个类,而IAction是需要实现的众多接口(interface)之一。

我的愿景是避免在 ActionDispatcher 中手动实现 IAction,但有某种注册机制,我可以说,ActionDispatcher 必须实现 IAction、IDoing、INoAction 等接口(interface) - 并为我生成调度方法。

MSDN 说,任何类都与任何接口(interface)兼容,所以我不需要在 ActionDispatcher 中声明“Implements”。但我仍然需要实现接口(interface)并将实现方法连接到接口(interface)定义,以便 WCF 在需要时可以找到它。

我发现的最接近的可能是 Automatic Interface Implementer ,但它 (1) 创建了一个新类型,(2) 添加了虚拟方法。

我也尝试过理解 CodeCompileUnit 类,但到目前为止还看不出与我需要的关系。

在 Reflection API 方面更有经验的人可以帮助我吗?有什么好方法可以做我想做的事吗?

最佳答案

我终于把它咬碎了。对于那些对复杂性感兴趣的人,解决方案(简而言之)是:

Class ActionDispatcher

    Private Shared mImplementorType As Type

    Public Shared Function GetImplementorType() As Type
        If mImplementorType Is Nothing
            mImplementorType = CreateImplementorType()
        End If

        Return mImplementorType
    End Function

    Private Shared Function CreateImplementorType() As Type
        ' Nice to have RunAndSave for debugging with ILdasm / ILSpy
        Dim myAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
            New AssemblyName() With { .Name = "ViewerDispatcherAssembly" },
            AssemblyBuilderAccess.RunAndSave)
        Dim mbuilder = myAssemblyBuilder.DefineDynamicModule("ViewerDispatcherModule", "ViewerDispatcherModule.dll")
        Dim tbuilder = mbuilder.DefineType("ViewerDispatcherImpl", TypeAttributes.Class Or TypeAttributes.Public)

        For Each itype In mInterfaceTypes
            tbuilder.AddInterfaceImplementation(itype)
            For Each method In itype.GetMethods()
                ' Create interface implementation for each interface method.
                CreateInterfaceImplementation(tbuilder, itype, method, capability, mbuilder)
            Next
        Next
        Return tbuilder.CreateType()
    End Sub
End Class

函数CreateInterfaceImplementation动态创建一个类型来保存接口(interface)参数,并在该类型中创建一个方法来调用正确的IAction函数。它还在 tbuilder 中创建 IAction 实现。 还有一个中间函数可以循环 mActionList 以最大限度地减少生成的代码量。

关于.net - 如何以编程方式(在运行时)向类添加接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10482101/

相关文章:

asp.net - Azure Application Insights 中报告 window.onerror 处的字符无效; ASP.Net Web 应用程序

c# - 使用 GetType() 进行转换

java - 使用反射迭代包中的类的方法

c# - 使用包含 .Net 中变量名称的字符串访问方法局部变量值

c# - 如何以编程方式在 netcf 中发送 TAB 击键

.net - 应对落后的枚举支持

c# - 使用异步/等待的 TransactionScope 登记

c# - 在结构上隐藏无参数构造函数

vb.net - PDF页面计数器

vb.net - 如何在VB.NET中从另一个窗体打开一个窗体?