I have a dynamic variable
dynamic d = GetSomeObject();
Sometime , in future, a user send me a function to execute ( its name) e.g "UsersGetAll"
So I need to do something like : d.UsersGetAll()
I can do it with reflection. But I want to use the DLR .
Does the only solution of doing this is to have MyObject inherit from DynamicObject and then implement TryInvokeMember?
What if I don't have control over the class ?
As Jon notes, the following really only applies if you suspect that the type is providing the method at runtime via the DLR; in most simple cases, reflection will be easier.
dynamic is intended when you know the method name but not the target. If you don't know the method name it is tricker. The tricky bit, perhaps, is ensuring you keep the call-site so that it can be re-used (which is how the DLR maintains performance). One cheeky way would be a static utility class that keeps track of invoked methods. Here's an example - note that it gets much messier if you need to handle parameters:
using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Collections;
using System.Runtime.CompilerServices;
public class Foo
{
public object Bar() { return "I was here"; }
}
static class Program
{
static void Main()
{
object obj = new Foo();
object result = DynamicCallWrapper.Invoke(obj, "Bar");
Console.WriteLine(result);
}
}
static class DynamicCallWrapper
{
// Hashtable has nice threading semantics
private static readonly Hashtable cache = new Hashtable();
public static object Invoke(object target, string methodName)
{
object found = cache[methodName];
if (found == null)
{
lock (cache)
{
found = cache[methodName];
if(found == null)
{
cache[methodName] = found = CreateCallSite(methodName);
}
}
}
var callsite = (CallSite<Func<CallSite, object,object>>)found;
return callsite.Target(callsite, target);
}
static object CreateCallSite(string methodName)
{
return CallSite<Func<CallSite, object, object>>.Create(
Binder.InvokeMember(
CSharpBinderFlags.None, methodName, null, typeof(object),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None, null) }));
}
}
I can do it with reflection. But I want to use the DLR.
Why? Assuming this is a "normal" object which isn't actually going to respond dynamically, reflection is going to be the easiest approach here.
The dynamic feature in C# 4 (in terms of the language feature) does absolutely nothing to help you here. It only allows dynamic binding of member names within C# source code.
Now you could:
Start an IronPython session, and create a tiny Python script to call the method using dynamic binding.
Use CSharpCodeProvider to compile some C# code using dynamic with the relevant method name, then execute that code.
Look at the generated code for your d.UsersGetAll() call, and basically emulate that.
All of these options are likely to be harder than reflection, if all you want it so call a "normal" method on a "normal" object, and you happen to only know the name at execution time.
Related
I am in a situation where i have to inherit a class and access its protected method to get a value.
Due to some weird situations i have most of my code in reflection and i m hoping if i have any chance to get this working using reflection.
To make things more clear,
Below is the class
public class Converter: BaseConverter
{
public Converter();
protected override object StringToValue();
}
I need to do below to get the functionality working.
public class myclass:Converter
{
public StringToValue()
{
base.StringToVaue();
}
}
However I cannot use direct reference of Converter dll in my project . So i am handicapped here to use inheritance and myclass : converter. So how can i approach this using reflection which would be to basically make myclass inherit the converter class at runtime. I am not sure if it makes sense or not however it seems to me that its where i am trying to head towards to get an answer
You can use TypeBuilder to create a whole new type at runtime via reflection. Of course ultimately you need a reference to the assembly which contains Converter to inherent from it. Make sure to check out the MSDN example of TypeBuidler. You need to call ModuleBuilder.DefineType() which has an overload to specify the parent type.
But if you go that way you have to do everything with reflection including emitting the methods. I don't fully understand your restrictions so that's the best answer I could think of but I don't really like it ;)
While we're talking about hacking: Do you really need to inherit from Converter or do you only need to access its methods? In case you only need the methods you could simply hold an instance of Converter as an attribute of type object and call the protected method via refletion inside your public StringToValue method.
EDIT:
As you ask for sample code. With reflection you can bypass the class security mechanism of C#, which means you're able to call non-public methods on any object. First you need the Type. Because you can't write it out in C# you need to get it some other way. Then you can create an instance of that type with Activator. You also need to obtain information about the method you want to call. It makes sense to cache this information because the processes of reading that information with reflection is kinda slow. Finally you can use the MethodInfo to actually call the method.
I haven't tested that code because I don't have a machine to do so right now.
class myclass
{
object internalConverter;
MethodInfo converterStringToValueMethod;
public myclass()
{
// Here you need a reference to the assembly which contains the Converter type
Assembly asm = Assembly.Load("xxx.dll"); // Name of the assembly which contains Converter
Type converterType = asm.GetType("Converter");
this.internalConverter = Activator.CreateInstance(converterType);
this.converterStringToValueMethod = converterType.GetMethod("StringToValue", BindingFlags.NonPublic | BindingFlags.Instance);
}
public object StringToValue()
{
return converterStringToValueMethod.Invoke(internalConverter, null);
}
}
This should do what you want without inheritance:
using System;
using System.Reflection;
namespace Test
{
class Converter
{
string Value;
public Converter(string test)
{
Value = test;
}
protected object StringToValue()
{
return Value;
}
}
class myclass
{
object Unknown;
public myclass(object other)
{
Unknown = other;
}
MethodInfo originalFunction;
public object StringToValue()
{
if (originalFunction == null)
{
originalFunction = Unknown.GetType().GetMethod("StringToValue", BindingFlags.NonPublic | BindingFlags.Instance);
}
return originalFunction.Invoke(Unknown, null);
}
}
class Test
{
[System.STAThread]
public static void Main(string[] args)
{
Converter unknown = new Converter("TEST");
myclass mine = new myclass(unknown);
Console.WriteLine(mine.StringToValue());
Console.ReadLine();
}
}
}
This is a bad idea for a number of reasons, but if you are sure it is what you need...
Hi I have a namespace with a lot of classes and all of them has a method Destroy(int id)
I want to call that method using dynamic word.
Here is my example:
public bool DeleteElement<T>(T tElement)
{
Type t = typeof(T);
dynamic element = tElement;
var id = element.Id;
//until here everything is fine
//here I want to say
(namespace).myClassName.Destroy(id);
//the name of myClassName is like t.ToString()
}
I can avoid namespace including a using at the top. The idea is to call that static method using dynamic, not Reflection, please see that Destroy is a static method of T. I need something like this T.Destroy(id)
If Destroy(int id) is a static method, couldn't you create an instance method that would call the static one?
public void Destroy()
{
ThisClass.Destroy(this.Id);
}
You could then define an IDestroyable interface implemented by all these classes:
interface IDestroyable { void Destroy(); }
And then modify your DeleteElement method as follows:
public bool DeleteElement<T>(T tElement) where T : IDestroyable
{
tElement.Destroy();
}
No need to use dynamic here... Actually, using dynamic in this situation is often an indication of bad design. It's quite rare to actually need dynamic except in the scenarios for which it was created (e.g. interop with dynamic languages)
(If the classes are generated but they have the partial modifier, you can declare the new method in another file that is not touched by the generator)
EDIT: if the classes are generated and are not partial, you can't modify them... So another solution would be to use reflection; I know you want to avoid that (for performance reasons I assume), but you can limit the performance impact by doing the reflection only once for each type: you just need to create and cache a delegate for each type.
class DestroyHelper<T>
{
static readonly Action<int> _destroy;
static readonly Func<T, int> _getId;
static DestroyHelper()
{
var destroyMethod = typeof(T).GetMethod("Destroy", BindingFlags.Static | BindingFlags.Public);
_destroy = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), destroyMethod);
var getIdMethod = typeof(T).GetProperty("Id").GetGetMethod();
_getId = (Func<T, int>)Delegate.CreateDelegate(typeof(Func<T, int>), getIdMethod);
}
public static void Destroy(T element)
{
_destroy(_getId(element));
}
}
This question already has answers here:
Calling a function from a string in C#
(5 answers)
Closed 9 years ago.
I was wondering if it was possible to call a function on a dynamic c# object via a string. I want to do something like this:
string lMethodName = "MethodName";
dynamic lDynamicObject = GetDynamicObject();
lDynamicObject.Invoke(lMethodName, lParameters);
Any thoughts or solutions would be greatly appreciated.
Maybe like Servy said there's a better way to achieve what we want through a different design. We're using SignalR and have a dashboard web app. We want each widget inside the dashboard to have the ability to have data pushed to it. To achieve this we were going to use razor code to inject the widget id into each individual widgets SignalR clientside proxy. Each widget would have something like the following:
hub.client.updateWidget123456 = aUpdateFunction;
Where 123456 is the id of the widget. On the serverside SignalR hub code we could call back into the clientside javascript function:
int lWidgetId = 123456;
dynamic lDynamic = Clients.All;
lDynamic.Invoke("updateWidget" + lWidgetId, lParameters);
There are other ways I can think of to implement this without creating the javascript proxy methods. I thought this was nice because the server had a direct communication line with each individual widget. Which could be accessed from multiple dashboards/browsers but they would all get updated via the single call above.
We could implement this instead by calling some other object in our javascript clientside code who knew about all the widgets and how to direct information to them. I felt like this went against the hub architecture of SignalR and like we were reinventing the wheel by doing this.
Does anyone have any thoughts on a better design approach? Thanks for the help and thanks for your comment Servy for sparking this discussion.
Also, this question is not a duplicate. The other question is not with regards to dynamic objects like Paul commented on below.
You can only use reflection to invoke a method on a dynamic if you know that it is an ordinary C# object (i.e. no special runtime binder).
Consider the following class that implements a property bag that can be used dynamically:
public class PropertyBag : DynamicObject
{
private Dictionary<string, object> _propertyBag = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _propertyBag.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_propertyBag[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return base.GetDynamicMemberNames();
}
}
It is perfectly valid to do the following:
dynamic propertyBag = new PropertyBag();
propertyBag.Name = "stackoverflow";
propertyBag.Value = 42;
If however you try to get the PropertyInfo for any of these dynamic properties it will fail because the PropertyBag class does not implement them:
public static void SetProperty(dynamic propertyBag, string propertyName, object value)
{
PropertyInfo property = propertyBag.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property == null)
{
throw new NotImplementedException();
}
MethodInfo setProperty = property.GetSetMethod();
setProperty.Invoke(propertyBag, new object[] { value });
}
This will throw an exception:
dynamic propertyBag = new PropertyBag();
propertyBag.Name = "stackoverflow; // works as expected
SetProperty(propertyBag, "Value", 42); // throws a NotImplementedException
I used properties in this example because they are easier to implement but obviously the same applies to methods too. The reason for this is that dynamic is dynamically evaluated at runtime but reflection can only reflect on the static implementation. (What properties should GetProperties return on the PropertyBag class?)
If you are using dynamic with ordinary C# objects reflection will work as expected but you cannot rely on that if you don't know what type of runtime binder you are adressing and how it is implemented internally.
By reflection I think you can do something like that (if it's private ->NonPublic)
MethodInfo dynMethod = this.GetType().GetMethod("MethodName" + itemType, BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod.Invoke(this, new object[] { methodParams });
Simply use the overloaded version of GetMethod that accepts BindingFlags:
Short answer, yes, you can do something like this:
class MyClass { public void Action() { Console.WriteLine("Do action"); } }
// ...
dynamic instance = new MyClass();
instance.GetType().GetMethod("Action").Invoke(instance, null);
However in this case, the fact that the instance is a dynamic type does absolutely nothing. You can use an object type and it will work the same way. The first method in the chain, GetType() returns the typeof(MyClass) and then it's plain old fasion reflection from there on out.
Using the dynamic keyword you can do this, which is far more interesting, albeit slightly less flexible at runtime:
dynamic instance = new MyClass();
instance.Action();
This will lookup the action at runtime using reflection. It isn't so obvious in this example that dynamic works differently from var because the MyClass is set here, but you could use the second line to execute ANY method named action so long as the instance had a method with that name.
Yes it is possible. What you want to do is called "reflection" and is available in most higher level languages
Here is an example of reflection in C. It is actually very powerful and allows you to make your code "aware of itself" up to a certain degree
I'm currently hosting IronPython in a .NET 2.0 application.
I want to create a class (in C#) whose instances can be "extended" by plugin instances. That means, each member access which is unresolvable on my instance should be forwarded to the appropriate plugin instance providing that member. My object will hold a private container with those plugin instances then.
AFAICS, the way to go there is via deriving from DynamicObject. The first step was easy so far that TryGetMember is called whenever python code uses "unknown" members of my instance. I also could return objects and delegates which could be used from the python code.
But, somehow, I got stuck when trying to use the DLR to perform the "subsearch" on the plugin instance and e. G. return a method or property of the plugin instance in the way IronPython expects it.
Any hints are welcome!
Thanks!
Edit: My original question was not formulated clear enough, sorry. Here some points:
The solution has to run with plain .NET 2.0, no .NET 3.5 or 4.0 allowed.
The plugin list are per instance (that means each instance can have a different - but immutable - list of plugin objects).
The plugin objects should be plain C# objects with all public members (or at least methods and properties) mapped.
Collision detection is not important.
Thanks again.
What it sounds like you want to do is have your plugin instances typed to object or dynamic (versus having them typed to some interface where you effectively pass through the TryGetMember request) and then perform a dynamic binding against another object. Luckily for you the DLR interop protocol allows for exactly this scenario! It'll require to drop down to the IDynamicMetaObjectProvider layer instead of using DynamicObject but it's actually pretty simple. I'll show you a simple example using InvokeMember that works end-to-end w/ C# 4.0. You'll need to go and do the rest of the operations - in particular IronPython will use GetMember instead of InvokeMember. But that's a straight forward process.
First an explanation of how you do it. At the IDMOP level the DLR deals with meta objects and languages request operations from meta objects and those meta objects return more meta objects. You can also ask the language to perform it's default binding and most importantly you can provide to it a suggestion of what to do when things go wrong.
Based upon that you can ask the language to try and bind to each one of your plugins and your own object. Depending on whether you want plugins to have precedence, or your dynamic object, you can perform the binding to yourself last. This sample demonstrates both techniques based upon the member names.
So without further delay, here it is:
using System;
using System.Dynamic;
using System.Linq.Expressions;
namespace ConsoleApplication10 {
class Program {
static void Main(string[] args) {
dynamic dynamicObj = new MyDynamicObject(new TestPlugin());
dynamicObj.Foo();
dynamicObj.Bar();
Console.ReadLine();
}
}
public class TestPlugin {
public void Foo() {
Console.WriteLine("TestPlugin Foo");
}
public void Bar() {
Console.WriteLine("TestPlugin Bar");
}
}
class MyDynamicObject : IDynamicMetaObjectProvider {
internal readonly object[] _plugins;
public void Foo() {
Console.WriteLine("MyDynamicObject Foo");
}
public void Bar() {
Console.WriteLine("MyDynamicObject Bar");
}
public MyDynamicObject(params object[] plugins) {
_plugins = plugins;
}
class Meta : DynamicMetaObject {
public Meta(Expression parameter, BindingRestrictions restrictions, MyDynamicObject self)
: base(parameter, restrictions, self) {
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) {
// get the default binding the language would return if we weren't involved
// This will either access a property on MyDynamicObject or it will report
// an error in a language appropriate manner.
DynamicMetaObject errorSuggestion = binder.FallbackInvokeMember(this, args);
// run through the plugins and replace our current rule. Running through
// the list forward means the last plugin has the highest precedence because
// it may throw away the previous rules if it succeeds.
for (int i = 0; i < Value._plugins.Length; i++) {
var pluginDo = DynamicMetaObject.Create(Value._plugins[i],
Expression.Call(
typeof(MyDynamicObjectOps).GetMethod("GetPlugin"),
Expression,
Expression.Constant(i)
)
);
errorSuggestion = binder.FallbackInvokeMember(pluginDo, args, errorSuggestion);
}
// Do we want DynamicMetaObject to have precedence? If so then we can do
// one more bind passing what we've produced so far as the rule. Or if the
// plugins have precedence we could just return the value. We'll do that
// here based upon the member name.
if (binder.Name == "Foo") {
return binder.FallbackInvokeMember(this, args, errorSuggestion);
}
return errorSuggestion;
}
public new MyDynamicObject Value {
get {
return (MyDynamicObject)base.Value;
}
}
}
#region IDynamicMetaObjectProvider Members
public DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter) {
return new Meta(parameter, BindingRestrictions.Empty, this);
}
#endregion
}
public static class MyDynamicObjectOps {
public static object GetPlugin(object myDo, int index) {
return ((MyDynamicObject)myDo)._plugins[index];
}
}
}
Running this prints:
MyDynamicObject Foo
TestPlugin Bar
Showing that for Foo members we prefer the binding on the actual object, and for Bar members we prefer Bar. If you add access to a third Baz member it produces C#'s runtime binder exception. If this was called from IronPython we'd produce an AttributeError to Python programs (a MissingMemberException in .NET) and a JavaScript implement should return undefined to their programs.
So you get not only your extensible plugin system you also easily get the correct behavior in any langauge which consumes your object.
I have a list of class names and methods that can only be read during runtime. Is it possible to create a class dynamically like that? I'm currently using C# 4.0.
It is a little unclear whether you want to define a type at runtime and define methods against it, or whether you want to create an instance of an already-written type, and call methods on it.
Fortunately both are possible.
The second scenario is more likely, so you'd want to look at reflection (below) - but note that there are performance penalties associate with this (and small things like "what arguments does the method take" become very important).
For the first scenario, you'd need to look at TypeBuilder, but that is much more complex. Another option would be CSharpCodeProvider and dynamic assembly loading, but again - not trivial by any stretch.
using System;
namespace MyNamespace {
public class Foo {
public void Bar() {
Console.WriteLine("Foo.Bar called");
}
}
}
class Program {
static void Main() {
string className = "MyNamespace.Foo, MyAssemblyName",
methodName = "Bar";
Type type = Type.GetType(className);
object obj = Activator.CreateInstance(type);
type.GetMethod(methodName).Invoke(obj, null);
}
}
To include parameters (comments) you pass an object[] instead of the null:
using System;
namespace MyNamespace {
public class Foo {
public void Bar(string value) {
Console.WriteLine("Foo.Bar called: " + value);
}
}
}
class Program {
static void Main() {
string className = "MyNamespace.Foo, MyAssemblyName",
methodName = "Bar";
Type type = Type.GetType(className);
object obj = Activator.CreateInstance(type);
object[] args = { "hello, world" };
type.GetMethod(methodName).Invoke(obj, args);
}
}
If you are doing this lots (for the same method) there is a way to improve performance via a typed delegate, but this doesn't gain you much for occasional calls.
You can use the IL emit functionality straight out of the .Net framework to accomplish this. You will need to learn IL in order to dynamically generate type information at runtime--this is not for the feint of heart.
Introduction to Creating Dynamic Types with System.Reflection.Emit
As I can't really answer that you are asking I will answer a number of question you might want to ask.
Can I create an instance of class and call its method where both class and method are specified at run time?
Sure. The simple way first. Use a if statements:
var className = "MyClass";
var methodName = "MyMethod";
if (className == typeof(MyClass).Name) {
var instance = new MyClass();
if (methodName == "MyMethod")
instance.MyMethod();
if (methodName == "MyOtherMethod")
instance.MyOtherMethod();
}
Alternatively, you can use Activator.CreateInstance to create an instance of a class for you.
var className = "MyClass";
var methodName = "MyMethod";
//Get a reference to the Assembly that has the desired class. Assume that all classes that we dynamically invoke are in the same assembly as MyClass.
var assembly = typeof(MyClass).Assembly;
//Find the type that we want to create
var type = assembly.GetTypes().FirstOrDefault(t=>t.Name == className);
if(type != null) {
//Create an instance of this type.
var instance = Activator.CreateInstance(type);
//Find the method and call it.
instance.GetType().GetMethod(methodName).Invoke(instance);
}
Can I generate a class at run time?
Yes you can but it's hard. If you are an experienced C# programmer, know a bit of C++ and assembly, you should be able to grock it. If not, don't bother.
Microsoft provides a library to emit Intermediate Language code called, surpose, IL.Emit. There are very few problems that warrant using this method, amongst those are mock object generation and some aspects of Dependency Injection. It is quite likely that your problem is better solved in another fashion.