Dan*_*rth 13 .net c# workflow-foundation workflow-foundation-4
如何从XAML加载WF4工作流程?重要细节:加载工作流的代码不需要事先知道工作流中使用的类型.
我很难从Visual Studio创建的XAML文件加载WF4工作流.我的方案是,我想将此文件放入数据库,以便能够集中修改它,而无需重新编译Workflow调用程序.
我目前正在使用此代码:
var xamlSchemaContext = new XamlSchemaContext(GetWFAssemblies());
var xmlReaderSettings = new XamlXmlReaderSettings();
xmlReaderSettings.LocalAssembly = typeof(WaitForAnySoundActivity).Assembly;
var xamlReader = ActivityXamlServices.CreateBuilderReader(
new XamlXmlReader(stream, xmlReaderSettings),
xamlSchemaContext);
var activityBuilder = (ActivityBuilder)XamlServices.Load(xamlReader);
var activity = activityBuilder.Implementation;
var validationResult = ActivityValidationServices.Validate(activity);
Run Code Online (Sandbox Code Playgroud)
这给了我很多错误,分为两类:
类别1:
我的程序集中的类型是未知的,尽管我为构造函数提供了正确的程序集XamlSchemaContext.
ValidationError {Message =编译器错误遇到处理表达式"GreetingActivationResult.WrongPin".'GreetingActivationResult'未声明.由于其保护级别,它可能无法访问.,Source = 10:VisualBasicValue,PropertyName =,IsWarning = False}
这可以通过使用此处描述的技术来解决,该技术基本上将所有使用类型的程序集和名称空间添加到某个VisualBasicSettings实例:
var settings = new VisualBasicSettings();
settings.ImportReferences.Add(new VisualBasicImportReference
{
Assembly = typeof(GreetingActivationResult).Assembly.GetName().Name,
Import = typeof(GreetingActivationResult).Namespace
});
// ...
VisualBasic.SetSettings(activity, settings);
// ... Validate here
Run Code Online (Sandbox Code Playgroud)
这可以工作,但使整个"动态加载"工作流的一部分成为一个笑话,因为代码仍然需要知道所有使用的命名空间.
问题1:是否有其他方法可以摆脱这些验证错误,而无需事先知道使用了哪些命名空间和程序集?
第2类:
我的所有输入参数都是未知的.我可以看到它们很好,activityBuilder.Properties但我仍然得到验证错误,说它们是未知的:
ValidationError {Message =编译器错误遇到处理表达式"Pin".'Pin'未声明.由于其保护级别,它可能无法访问.,Source = 61:VisualBasicValue,PropertyName =,IsWarning = False}
到目前为止还没有解
问题2:如何告诉WF4使用XAML文件中定义的参数?
小智 11
问题2:您无法执行ActivityBuilder,它仅用于设计.您必须加载DynamicActivity(仅通过ActivityXamlServices).它应该以这种方式工作(不使用特殊的XamlSchemaContext),但你必须事先加载所有使用的程序集(将它们放在bin目录中也应该有效,到目前为止关于问题1,DynamicActivity可能会使事情变得更容易一些):
var dynamicActivity = ActivityXamlServices.Load(stream) as DynamicActivity;
WorkflowInvoker.Invoke(dynamicActivity);
Run Code Online (Sandbox Code Playgroud)
总的来说,我的印象是你试图实现自己的"ActivityDesigner"(比如VS).我自己尝试了这个,并且很难处理DynamicActivity和ActivityBuilder(因为DynamicActivity不可序列化,但是ActivityBuilder无法执行),所以我最终得到了一个自己的活动类型,它在内部将一种类型转换为另一种类型.如果你想看看我的成果,阅读的最后部分这篇文章.