首页 > 解决方案 > 创建表达式从带有重载构造函数的方法名

问题描述

我正在使用 Hangfire,并且有一种方法可以按程序集、类型和方法名称来安排作业。使用默认构造函数可以正常工作,但所有方法都具有将使用 Autofac 激活的重载构造函数。

//Works for a default constructor
Type type = Type.GetType("typestring, assemblystring");
var method = type.GetMethod("methodstring");
Expression[] args = new Expression[] { Expression.Constant(options,typeof(Options)) }; //All methods use the same parameters
var action = Expression.Lambda<Action>(Expression.Call(Expression.New(type), method, args));
RecurringJob.AddOrUpdate(action, "cronstring");

尝试修改以支持重载构造函数(无默认值)我有这段代码。

Type type = Type.GetType("typestring, assemblystring");
var method = type.GetMethod("methodstring");
Expression[] args = new Expression[] { Expression.Constant(options,typeof(Options)) }; //All methods use the same parameters
var ctor = type.GetConstructors().ToList().FirstOrDefault();
var ctorParams = ctor.GetParameters();
var ctorArgs = new Expression[ctorParams.Length];
for (int i = 0; i != ctorParams.Length; ++i)
{
   ParameterExpression param = Expression.Parameter(typeof(object), ctorParams[i].Name);
   ctorArgs[i] = Expression.Convert(param, ctorParams[i].ParameterType);
}            
var ctorExpress = Expression.New(ctor, ctorArgs);
var action = Expression.Lambda<Action>(Expression.Call(ctorExpress, method, args));
RecurringJob.AddOrUpdate(action, "cronstring"); 

我收到此错误:InvalidOperationException:从范围“”引用的“System.Object”类型的变量“{first constructor param}”,但未定义

我不确定我是否遗漏了某些东西或在这方面走错了路。我使用表达式的经验有限。

标签: c#autofacexpression-treeshangfire

解决方案


谢谢@ASpirin,您的意见帮助解决了这个问题。我将构造函数的参数更改为Constant代替Parameter并传入null.

Type type = Type.GetType("typestring, assemblystring");
var method = type.GetMethod("methodstring");
Expression[] args = new Expression[] { Expression.Constant(options,typeof(Options)) }; //All methods use the same parameters
var ctor = type.GetConstructors().ToList().FirstOrDefault();
var ctorParams = ctor.GetParameters();
var ctorArgs = new Expression[ctorParams.Length];
for (int i = 0; i != ctorParams.Length; ++i)
{
   var param = Expression.Constant(null,typeof(object)); //Updated this line
   ctorArgs[i] = Expression.Convert(param, ctorParams[i].ParameterType);
}            
var ctorExpress = Expression.New(ctor, ctorArgs);
var action = Expression.Lambda<Action>(Expression.Call(ctorExpress, method, args));
RecurringJob.AddOrUpdate(action, "cronstring");

这可以工作,因为 Hangfire 实际上并没有执行构造函数并像这样保存表达式:

//Class name is Test, method name is Run
var test = Activate<Test>();
test.Run(FromJson<Options>("REMOVED"));

Activate<Test>在另一个程序中使用 Autofac 激活。


推荐阅读