【发布时间】: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