2

I am looking for a way to add an interface implementation to a class at runtime. Here is a sample code, which I will discuss below.

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

This is related to WCF, where one needs to provide to CreateHost a single class, which implements all interfaces required for the end points. In this scenario, ActionDispatcher is such a class, and IAction is one of the many interfaces to be implemented.

My vision is to avoid implementing IAction in ActionDispatcher manually, but have some sort of registration mechanism, where I can say, that ActionDispatcher must implement interfaces IAction, IDoing, INoAction, etc - and have the dispatching methods generated for me.

MSDN says, that any class is compatible with any interface, so I don't need to declare "Implements" in the ActionDispatcher. But I still need to implement the interface and connect the implementing method to the interface definition, so WCF can find it when needed.

The closest thing I found is probably the Automatic Interface Implementer, but it (1) creates a new type, (2) adds dummy methods.

I has also tried to understand CodeCompileUnit class, but so far couldn't see the relation to what I need.

Can someone more experienced in Reflection API help me out? Is there a nice way to do whay I want?

1
  • I am on my way through this exercise. I guess, the most I'd want now is to not mess with IL (which is as self-explanatory as Assembler, and as much error-prone as well), but generate IL code from string :-) Something like <code>Compiler.CompileToIL("Public Sub DoThat(a As Integer) Implements ... End Sub")</code> Commented May 10, 2012 at 10:50

4 Answers 4

2

I finally crunched it. For those interested in the intrications, the solution (in short) is:

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

The function CreateInterfaceImplementation dynamically creates a type to hold interface parameters and a method in this type to call the correct IAction function. It also creates the IAction implementation in tbuilder. There also exists an intermediate function to loop through mActionList to minimize the amount of the generated code.

Sign up to request clarification or add additional context in comments.

Comments

0

First, this seems like a lot of work trying to avoid few lines of code. If you want a class to implement an interface, just specify that, that's how the .Net type system works.

And actually, you can't really do what you want. You can't modify the code of a class at runtime. The best you can hope for is to create a new type that implements the interface. But if you don't want to create new types at runtime (why?), then I think you're out of luck.

7 Comments

I investigated it a bit further. You're right, creating new types at runtime is my only way out. Why? Well, I like automatics :-) Adding a new interface must be as painless as possible, hence decoupling it from everything possible is my target.
But it doesn't make much sense to decouple interfaces from classes. When you're writing the class, you need to know about the interfaces it's going to implement, to know which members to implement (and how), so you might just as well specify the interface explicitly.
Why not? If you have 50 interfaces to implement, you don't want to make a lot of duplicated code. If I just provide a list of interfaces to implement, and it does the job - this is more robust.
If you have 50 interfaces to implement in one class, then you're most likely doing something wrong. And I really don't see how would that make your code more robust, you're just trying to avoid a small amount of typing.
@MikNik i have to agree with svick. This magic wil bite you soon. If you are generating implementations it means your implementation probably belongs somewhete else. You are almost certainly doing something wrong. Implementations are very specific. It just doesnt make sense to auto generate it. Unless it is a mock for testing or something similar.
|
0

I've heard of writing property values by using reflection, but injecting new properties and methods to an existing type at runtime? Sounds a little too futuristic to me.

Even if it was possible, interfaces are used to define a set of properties and/or methods that are always present in the type that implements them. If you could indeed add or remove the implementations at will, it would most likely break any other type that relies on your class in one way or another.

Comments

0

You can try some sort of mixins using Castle Dynamic Proxy. http://www.codeproject.com/Articles/9055/Castle-s-DynamicProxy-for-NET But also creates a new type (the proxy), so maybe you don't like it either....

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.