3

我的最终目标是创建一个函数,该函数将动态地将方法名称传递给 Hangfire 库中的类。

例如,这是有效的非动态代码:

RecurringJob.AddOrUpdate(() => myFunction(), Cron.Hourly)

AddOrUpdate 的第一个参数的类型是Expression<Action>。我的第一步是使用反射来动态插入函数名:

Type thisControllerType = this.GetType();
MethodInfo method = thisControllerType.GetMethod(methodName); //methodName passed as string parameter
RecurringJob.AddOrUpdate(() => method.Invoke(this, null), Cron.Hourly);

当我检查 Hangfire 仪表板时,似乎这个表达式被评估为MethodBase.Invoke. 所以我需要帮助动态传递方法名称。

这可能足以回答我的问题,但我采取的另一条路径是尝试为论点生成整个表达式。

RecurringJob.AddOrUpdate(CreateCallExpression(method), Cron.Hourly);

public Expression<Action> CreateCallExpression(MethodInfo method)
    {
        //trying to pass in zero argument parameter, not sure if this syntax is correct    
        var parameter = System.Linq.Expressions.Expression.Parameter(typeof (Array));
        return System.Linq.Expressions.Expression.Lambda<Action>(System.Linq.Expressions.Expression.Call(method, parameter));
    }

在这种情况下,我收到异常 {“静态方法需要空实例,非静态方法需要非空实例。\r\n参数名称:方​​法”}。我正在努力,但不确定这是否是我应该走的路。我整天都在做这件事,所以我希望有人能帮助我加快学习速度。

4

1 回答 1

2

您的第二个实例将用于创建指向您指定方法的指针,但要解决您的静态问题,您只需以两种方式之一修改以下行。首先,您可以通过声明您寻求为静态的方法并修改这行代码来完成静态引用:

System.Linq.Expressions.Expression.Call(method, parameter);

您必须为调用方法提供一个空参数,因为如果您正在搜索静态方法,那么编译器将确切知道您想要什么方法签名,因为只会存在 1。代码行将更新为:

System.Linq.Expressions.Expression.Call(null, method, parameter); 

第二种方法是定义与方法相关的类或“实例”,以便编译器知道要搜索哪个类来查找方法签名。您将不得不像这样修改您的代码:

var myInstance = Expression.Parameter(typeof(MyClass), "inst");
System.Linq.Expressions.Expression.Call(myInstance, method, parameter)

我建议查看Call的文档,以便准确了解指针是如何创建的。

于 2014-10-16T18:35:57.723 回答