Using DynamicObject (IDynamicMetaObjectProvider) as a component of a static type leads to infinite loop
c#-4.0, dynamic
Solution
I think the problem is that the `Expression` parameter passed to `GetMetaObject` represents the target of the dynamic invocation (i.e. the current object). You are passing the outer object to the call on `component.GetMetaObject`, so the returned meta object is trying to resolve the call to `AMethod` on the outer object instead of itself, hence the infinite loop.
You can create your own meta object which delegates to the inner component when binding member invocations:
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new DelegatingMetaObject(component, parameter, BindingRestrictions.GetTypeRestriction(parameter, this.GetType()), this);
}
private class DelegatingMetaObject : DynamicMetaObject
{
private readonly IDynamicMetaObjectProvider innerProvider;
public DelegatingMetaObject(IDynamicMetaObjectProvider innerProvider, Expression expr, BindingRestrictions restrictions)
: base(expr, restrictions)
{
this.innerProvider = innerProvider;
}
public DelegatingMetaObject(IDynamicMetaObjectProvider innerProvider, Expression expr, BindingRestrictions restrictions, object value)
: base(expr, restrictions, value)
{
this.innerProvider = innerProvider;
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
var innerMetaObject = innerProvider.GetMetaObject(Expression.Constant(innerProvider));
return innerMetaObject.BindInvokeMember(binder, args);
}
}
}
Problem
I'm trying to create a dynamic object that can be used as a component of a static object. Here is a contrived example of what I'm trying to accomplish. Here is the dynamic component: ``` public class DynamicComponent : DynamicObject { public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, out object result) { result = "hello"; return true; } } ``` And here is a class where inheriting from `DynamicObject` isn't an option...assume that there is some third party class that I'm forced to inherit from. ``` public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider { IDynamicMetaObjectProvider component = new DynamicComponent(); public DynamicMetaObject GetMetaObject(Expression parameter) { var result = component.GetMetaObject(parameter); return result; } } ``` The direct usage of `DynamicComponent` works: ``` dynamic dynamicComponent = new DynamicComponent(); Assert.AreEqual(dynamicComponent.AMethod(), "hello"); ``` However, forwarding the `GetMetaObject` through `AStaticComponent` causes some form of an infinite loop. ``` dynamic dynamicComponent = new AStaticComponent(); Assert.AreEqual(dynamicComponent.AMethod(), "hello"); //causes an infinite loop ``` Anyone know why this occurs? And if it's some baked in behavior of `DynamicObject` that I cannot change, could someone provide some help on how to create a `IDynamicMetaObjectProvider` from scratch to accomplish a component based dynamic object (just something to get things started)?