3

I have a DynamicObject-based class that implements an interface dynamically (via TryGet* and TryInvoke*). I want to call the methods that it implements using reflection. The problem is that it throws a TargetException (Object does not match target type).

Like I said, it's dynamic, so it forwards the calls via a series of connections as text to another program, which then calls the destination method using reflection. It is basically a proxy class. The method names are known at compile time (because of the interface), but are called externally.

typeof(ITelescope).GetMethod(Console.ReadLine()).Invoke(prox,null);

ITelescope is the interface, prox is the dynamic object.

1
  • Could you post some code demonstrating the issue please? Commented Oct 22, 2012 at 17:06

3 Answers 3

4

Unfortunately, dynamically defined methods are not available via reflection. Part of this is due to the fact that they are truly dynamic - you could have a dynamic object where ANY method was valid, so there is no way for reflection to work properly in that scenario. (ie: what would GetMethods() return?)

If the object is a dynamic object, the best option is usually to just assign it to a dynamic, and use the dynamic binding to get your method call:

dynamic yourObj = prox;
yourObj.Unpark();
Sign up to request clarification or add additional context in comments.

4 Comments

Did you meant "dynamically defined methods are NOT avaiable via reflection"?
This does not work because I do not know the method name at compile time. Sorry, I should have included that in my question, I thought it was self-evident. I guess my code bit was a bit misleading. I've edited it to reflect that.
Everything is working off of the interface. It should then just invoke it in the prox object but it acts like it is a Typed object instead of a dynamic object. The invoke method should go through the normal process of calling TryInvokeMember.
@ArlenBeiler If the object doesn't actually implement the interface (only dynamically provides the interface's members), then invoking via the interface won't work, since C# is statically typed at it's core, and doesn't directly support duck typing. In this case, using a library like jbtule mentioned might be a simpler approach (as you need to get the proper runtime binder to call the member, which isn't simple)
3

Although you can not invoke a dynamic method with reflection, you can invoke TryGet.../TryInvoke... methods of DynamicObject which in turn execute your dynamic method...

dynamic obj = new MyDyn();
Console.WriteLine(obj.Text);

string methodName = "YourDynamicMethod";                    

var p1 = new ParameterModifier(2);
p1[0] = false; p1[1] = true;

var args = new object[] { new MemberBinder(methodName, true), null };

var res = typeof(DynamicObject).InvokeMember(
    "TryGetMember",
    BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
    null,
    obj,
    args,
    new ParameterModifier[] { p1 },
    null,
    null);

var result = args[1];

public class MyDyn : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = "#" + binder.Name + "#";
        return true;
    }
}

public class MemberBinder : GetMemberBinder
{
    public MemberBinder(string name, bool ignoreCase) : base(name, ignoreCase)
    {
    }

    public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
    {
        throw new NotImplementedException();
    }
}

1 Comment

I don't get what that's for either. Looks good to me, I'm upvoting it. Seems like the best solution when you don't want or can't add a 3rd party dependency such as Impromptu. There're are other target clients such as WinRT when such thing is not feasible.
3

If your trying to do something a little more meta than just using the dynamic keyword, you might be interested in a framework I wrote ImpromptuInterface (apache licensed, can be found in nuget).

Since it looks like you have an interface that matches up with your dynamic object, you can use Impromptu to wrap your dynamic object with an interface impromptu will dynamically emit an object that statically has an interface and will forward calls from that interface to a dynamic object using the dlr.

ITelescope iprox = Impromptu.ActLike(prox);
prox.Unpark();

Or if you just want to call a method of a dynamic object by a string name, similar to reflection, it also has a bunch of reflection like methods, that dynamically invoke dlr calls. It is less efficient than the interface way, but more efficient than reflection.

Impromptu.InvokeMember(prox,"Unpark");

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.