如何在MORYX中定义带构造参数的TaskStep<T1,T2>并解决实例化异常
问题描述
尝试创建带有构造函数参数的TaskStep<T1,T2>实现,代码如下:
[Display(Name = "Some Task", Description = "Task which does something with a product")] public class SomeTask : TaskStep<SomeActivity, SomeParameters> { public SomeTask([Display(ResourceType = typeof(Strings), Name = nameof(Strings.SOME_PARAMETER))] string someParameter) { } }
导入包含该任务的工作流可正常执行,Moryx.Workplans.Web编辑器拖拽步骤创建时也能正常要求输入参数,但保存或加载包含该步骤的工作流时,收到500 HTTP响应,核心异常信息如下:
System.MissingMethodException: Cannot dynamically create an instance of type 'Moryx.Demo.Activities.SomeTask'. Reason: No parameterless constructor defined. at System.RuntimeType.ActivatorCache..ctor(RuntimeType rt) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions) at Moryx.Products.Management.RecipeStorage.LoadSteps(WorkplanEntity workplan, IDictionary`2 connectors) ...
解决方案
Moryx框架的RecipeStorage组件在序列化、反序列化工作流步骤时,依赖公共无参构造函数动态创建实例,这是触发异常的根本原因。正确定义带参数配置的TaskStep需遵循以下规范:
1. 必须添加无参构造函数
为SomeTask显式添加公共无参构造函数,即使是空实现,供框架加载时调用:
[Display(Name = "Some Task", Description = "Task which does something with a product")] public class SomeTask : TaskStep<SomeActivity, SomeParameters> { // 框架加载步骤时必须调用的无参构造函数 public SomeTask() { } // 带参数的构造函数可保留,供手动实例化场景使用 public SomeTask(string someParameter) { // 将参数值映射到Parameters属性(推荐方式) Parameters.SomeParameter = someParameter; } }
2. 配置参数放在Parameters类中
Moryx工作流的设计规范中,步骤的配置参数必须通过泛型参数TParameters(即你的SomeParameters类)承载,而非构造函数参数:
// 继承WorkplanParameters定义自定义参数类 public class SomeParameters : WorkplanParameters { [Display(ResourceType = typeof(Strings), Name = nameof(Strings.SOME_PARAMETER))] public string SomeParameter { get; set; } }
这样编辑器会自动识别SomeParameters中的属性作为配置项,框架在持久化和加载工作流时,会通过序列化该参数类来保存、恢复配置,完全无需依赖构造函数传递参数。
3. 构造函数的正确用途
构造函数仅适合注入框架依赖的服务(如通过DI容器注入的业务服务),工作流的用户配置参数绝对不能通过构造函数传递,否则会破坏框架的持久化逻辑。
内容的提问来源于stack exchange,提问作者1nf0rmagician
相关产品推荐
相关产品推荐

