14

Can I define a class which derives from DynamicObject and supports an interface (ICanDoManyThings) without having to implement each method in the interface?

I'm trying to make a dynamic proxy object, and want the method invocations on this class to be handled by the implementation of MyProxyClass.TryInvokeMember, which may or may not pass them on to a wrapped object.

Is this possible?

Thanks

gap
  • 2,766
  • 2
  • 28
  • 37
  • 1
    Possible duplicate of [Dynamically implementing an interface in .NET 4.0 (C#)](https://stackoverflow.com/questions/2974736/dynamically-implementing-an-interface-in-net-4-0-c) – N-ate Apr 10 '19 at 18:12

3 Answers3

12

ImpromptuInterface does exactly this and it works with ANY IDynamicMetaObjectProvider including DynamicObject subclasses and ExpandoObject.

using ImpromptuInterface;
using ImpromptuInterface.Dynamic;

public interface IMyInterface{

   string Prop1 { get;  }

    long Prop2 { get; }

    Guid Prop3 { get; }

    bool Meth1(int x);
}

...

//Dynamic Expando object
dynamic tNew = Build<ExpandoObject>.NewObject(
         Prop1: "Test",
         Prop2: 42L,
         Prop3: Guid.NewGuid(),
         Meth1: Return<bool>.Arguments<int>(it => it > 5)
);

IMyInterface tActsLike = Impromptu.ActLike<IMyInterface>(tNew);

Linfu won't actually use DLR based objects and rather uses it's own naive late binding which gives it a SERIOUS performance cost. Clay does use the dlr but you have to stick with Clay objects which are designed for you to inject all behavior into a ClayObject which isn't always straightforward.

jbtule
  • 31,383
  • 12
  • 95
  • 128
  • Does this work if I write my own expando and call `ActLike`? Like, `dynamic tNew = new ExpandoObject(); tNew.Prop1 = "Test";` ...etc... and `Impromptu.ActLike(tNew);` ? – nawfal Aug 10 '14 at 07:23
  • 1
    Yes it works with any `IDynamicMetaObjectProvider`, as it uses the C# `dynamic` keyword api's. – jbtule Aug 11 '14 at 12:58
3

With Clay, you can.

An example:

public interface IMyInterface
{
    string Prop1 { get; }

    long Prop2 { get; }

    Guid Prop3 { get; }

    Func<int, bool> Meth { get; }
}

//usage:

dynamic factory = new ClayFactory();
var iDynamic = factory.MyInterface
(
    Prop1: "Test",
    Prop2: 42L,
    Prop3: Guid.NewGuid(),
    Meth: new Func<int, bool>(i => i > 5)
);

IMyInterface iStatic = iDynamic;

This article shows few more ways to achieve this.

nawfal
  • 70,104
  • 56
  • 326
  • 368
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • It's better to install ClaySharp from nuget rather than Clay since the latter has a dependency with Castle.Core project (unfortunately doesn't work with latest Castle.Core as well) while the former has no dependency issues. – nawfal Aug 10 '14 at 10:13
  • While Clay offers a great deal of flexibility I like the approach of Impromptu. Pretty straightforward. Another case, Clay doesn't play well with interfaces having methods. – nawfal Aug 10 '14 at 10:17
1

Check out LinFu's proxies, mixins and duck typing.

vgru
  • 49,838
  • 16
  • 120
  • 201
  • 1
    linfu uses it's own invention for a DynamicObject that was pre-DLR. Upside is that it works with .net 3.5, downside it can be painfully slow. – jbtule Jul 18 '11 at 13:12