我正在寻找一种在运行时向类添加接口实现的方法。 这是一个示例代码,我将在下面讨论。
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提供单个类,该类实现端点所需的所有接口。在这种情况下,ActionDispatcher就是这样一个类,而IAction是要实现的众多接口之一。
我的目标是避免手动在ActionDispatcher中实现IAction,但我可以说有一些注册机制,ActionDispatcher必须实现接口IAction,IDoing,INoAction等 - 并为我生成调度方法。 / p>
MSDN说,任何类都与任何接口兼容,所以我不需要在ActionDispatcher中声明“Implements”。但是我仍然需要实现接口并将实现方法连接到接口定义,因此WCF可以在需要时找到它。
我找到的最接近的东西可能是Automatic Interface Implementer,但它(1)创建了一个新类型,(2)添加了虚拟方法。
我也尝试了解CodeCompileUnit类,但到目前为止还看不到与我需要的关系。
在Reflection API中有经验的人可以帮助我吗?有什么好方法可以做我想要的吗?
答案 0 :(得分:2)
我终于嘎吱作响了。对于那些对复杂感兴趣的人,解决方案(简而言之)是:
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
动态创建一个类型来保存接口参数,并使用此类型的方法来调用正确的IAction
函数。它还会在IAction
中创建tbuilder
实施。
还存在一个循环mActionList
的中间函数,以最小化生成的代码量。
答案 1 :(得分:0)
首先,这似乎是在尝试避免几行代码的大量工作。如果你想让一个类实现一个接口,只需指定一下,这就是.Net类型系统的工作方式。
实际上,你不能真正做你想做的事。您无法在运行时修改类的代码。您可以期望的最好的方法是创建一个实现接口的新类型。但是如果你不想在运行时创建新类型(为什么?),那么我认为你运气不好。
答案 2 :(得分:0)
我听说过使用反射编写属性值,但是在运行时将新属性和方法注入现有类型?对我来说听起来有点太未来了。
即使可能,接口也用于定义一组在实现它们的类型中始终的属性和/或方法。如果您确实可以随意添加或删除实现,那么它很可能会破坏以某种方式依赖于您的类的任何其他类型。
答案 3 :(得分:0)
您可以使用Castle Dynamic Proxy尝试某种混音。 http://www.codeproject.com/Articles/9055/Castle-s-DynamicProxy-for-NET 但是也会创建一个新类型(代理),所以也许你不喜欢它......