Dynamically implementing an interface in .NET 4.0 (C#)
Asked Answered
C

5

48

With the new dynamic capabilities in .NET 4.0, it seems like it should be possible to dynamically implement an interface, e.g. given:

public interface IFoo 
{
    string Bar(int baz);
}

public class Foo : IFoo
{
    public string Bar(int baz) { return baz.ToString(); }
}

public class Proxy : IDynamicMetaObjectProvider
{
    private readonly object target;

    public Proxy(object target) { this.target = target; }

    // something clever goes here
}

Then I'm hoping there is some way to make it possible to write:

dynamic proxy = new Proxy(new Foo());
IFoo fooProxy = (IFoo)proxy; // because the target object implements it
string bar = fooProxy.Bar(123); // delegates through to the target implementation

But, as yet, I'm unsure what to replace // something clever goes here with.

So, my questions are:

  1. Is this actually possible to do with the dynamic runtime? It appears that dynamically implementing things like methods and properties is fairly easy, but I haven't found any documentation about dynamically implementing interfaces and conversions to them.

  2. Assuming this is possible, how difficult is it likely to be? (You can assume I'm a decent programmer with plenty of experience of things like reflection, but new to the dynamic framework.)

  3. Are there any resources which would help to point me in the right direction for implementing something like this? Or even samples where this kind of thing has already been done that I can use as a starting point?

Comment answered 4/6, 2010 at 13:55 Comment(1)
Where's the code that implements the interface methods going to come from?Guria
M
14

As far as I know, it's not possible without manual intervention to write or generate code that forwards the interface members to the wrapped instance. If you would like to see Microsoft-provided support for this sort of thing, you might want to consider voting at https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member .

Microampere answered 4/6, 2010 at 14:14 Comment(1)
I think the feedback moved to visualstudio.uservoice.com/forums/121579-visual-studio-ide/… but that closed. C# feature requests should now go to github.com/dotnet/csharplangExothermic
M
47

The opensource framework Impromptu-Interface was designed to do this. It generates a cached lightweight proxy with a static interface and uses the dlr to forward the invocation to the original object.

using ImpromptuInterface;

public interface ISimpeleClassProps
{
    string Prop1 { get;  }

    long Prop2 { get; }

    Guid Prop3 { get; }
}

-

dynamic tOriginal= new ExpandoObject();
tOriginal.Prop1 = "Test";
tOriginal.Prop2 = 42L;
tOriginal.Prop3 = Guid.NewGuid();

ISimpeleClassProps tActsLike = Impromptu.ActLike(tOriginal);
Malissa answered 28/2, 2011 at 17:54 Comment(1)
What a great framework. I have found myself using this often.Audiology
M
14

As far as I know, it's not possible without manual intervention to write or generate code that forwards the interface members to the wrapped instance. If you would like to see Microsoft-provided support for this sort of thing, you might want to consider voting at https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member .

Microampere answered 4/6, 2010 at 14:14 Comment(1)
I think the feedback moved to visualstudio.uservoice.com/forums/121579-visual-studio-ide/… but that closed. C# feature requests should now go to github.com/dotnet/csharplangExothermic
H
5

I think I wrote a library that does what you want... It is called DynamicWrapper (on CodePlex) and it will automatically wrap a a class so it implements an interface. Is this what you want?

Hydrastine answered 4/6, 2010 at 14:0 Comment(2)
It's the same idea, but it looks like your wrapper uses reflection emit? That's what we're using to do this at the moment as well, but I'm curious as to whether it could be done with the dynamic framework instead of having to use reflection emit.Comment
Code samples so it's not a "link only" ish answer?Jeconiah
A
3

Explicit casting, as, and is fail because of type comparison would against your proxy base class, but implicit cast can trigger DynamicObject.TryConvert, such that you can then return inner object in-lieu of the dynamic object.
- TryConvert MSDN Documentation

While the code below works, this isn't interface delegation per se, only exposure of internal state. It sounds like you might be looking for something like an interception pattern such as Brian's DynamicWrapper.

dynamic wrapper = new Proxy(new Foo());
IFoo foo = wrapper;
foo.Bar();

class Proxy : DynamicObject
{
    ...

    public override bool TryConvert(ConvertBinder binder, out object result)
    {
        Type bindingType = binder.Type;
        if (bindingType.IsInstanceOfType(target))
        {
            result = target;
            return true;
        }
        result = null;
        return false;

    }

}
Arthrospore answered 4/6, 2010 at 15:27 Comment(2)
+1, but I didn't follow: why does explicit casting fails? It's curious because ConvertBinder has the Explicit property to query for that.Guildroy
Jordão it seems that unlike implicit casting syntax which generates a Binder.Convert call in the generated IL, the "is" and "as" syntax omit testing for conversion. i.e. in the q) example clearly the type Foo != type Proxy.Arthrospore
B
3

Complementing the answer from @jbtule I have created my CustomActivator that is able to create a dynamic object at runtime and make it implements a desired interface. I also use the Impromptu-Interface framework to accomplish that.

The call is simple:

CustomActivator.CreateInstance<MyInterface>();

I put it on github.

Banter answered 17/5, 2015 at 3:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.