【问题标题】:Execute any method by string with parameters通过带参数的字符串执行任何方法
【发布时间】:2011-12-16 14:15:25
【问题描述】:

我一直在修改作为个人项目制作的 CMS,但我已经到了一个我坚持下去的地步。

基本上我有一个插件管理器,它在运行时加载程序集,查找标有自定义属性的方法,并使这些方法可以从我编写的模板引擎中调用。

我有模板引擎将模板解析为表达式,这些表达式被编译成一个我可以缓存和调用的函数。此模板中有少量代码被解析以执行不同的操作,例如调用插件上的方法。

模板代码示例:

到目前为止,我已经正确解析了这个,方法名称和参数为字符串、整数、布尔值等。

我编写的插件管理器也可以正常工作,但我无法将两者连接在一起。

比如说这是一个插件类:

[Plugin(Name="Test")]
public class TestPlugin
{
    private DateTime _startTime;

    public TestPlugin()
    {
        _startTime = DateTime.Now;
    }

    [TemplateAction]
    public string Test(int number, string testString)
    {
        return "TEST";
    }
}

我需要能够从我解析的模板中调用 Test() 并将模板中的任何参数传递给方法。我从标有属性的方法创建了一个 System.Delegate,并在模板引擎中添加了一个表达式作为缓存方法的一部分来调用 Test()。

我不知道如何将解析后的参数从模板传递到方法中。我试图创建一个 object[] 并将其传递给委托上的 DynamicInvoke 但它抱怨参数不匹配,所以我有点卡住了。我不确定您是否可以通过表达式将 object[] 传递给具有 (params object[] args) 作为签名的方法。

性能也是 DynamicInvoke 的一个问题,所以如果有一种方法可以在不使用 DynamicInvoke 的情况下实现这一点,或者创建一些我可以缓存的东西,那就太好了。

抱歉,如果不清楚,请随时提出任何问题。

非常感谢任何帮助。

瑞克。

更新

经过一番思考后好的,感谢 D Stanley 我做到了。

foreach (var method in type.GetMethods().Where(x => x.GetCustomAttributes(typeof(TemplateActionAttribute), true).Length > 0))
{
    if (method.ReturnType != typeof(string)) continue;

    PluginTemplateActions.Add(method.Name, o => (string)method.Invoke(plugin, o));
}

到目前为止,它的工作方式正是我想要的,但这也会比 DynamicInvoke 更快吗?

【问题讨论】:

  • 你是如何声明委托的?应该是Func<int, string, string> - 这就是你所拥有的吗?
  • 为了创建委托,我有这个,Delegate.CreateDelegate(Expression.GetFuncType(args.ToArray()), null, method);

标签: c# reflection expression templating


【解决方案1】:

你可以使用反射:

TestPlugin plugIn = new TestPlugin();
object[] params = null //... set parameters here
MethodInfo mi = typeof(TestPlugin).GetMethod("Test");
mi.invoke(plugIn,params);

【讨论】:

  • 其实你应该使用GetMethod而不是GetProperty
  • 啊,有趣!我已经有插件方法的 MethodInfo,我没有看到 Invoke 方法!我会找个修补匠,看看能不能把它分类。
猜你喜欢
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 2020-05-26
  • 1970-01-01
  • 2021-05-29
  • 2019-07-20
  • 1970-01-01
相关资源
最近更新 更多