给大家分享一下,如何完全使用代码自定义的创建生成工作流文件(用代码创建Xaml文件),并且动态加载运行所生成的工作流。

工作流生成后 在Xaml文件里的主要节点如下:

输入输出参数

  <x:Members>
<x:Property Name="Item" Type="InArgument(qm:RuleModel)" />
<x:Property Name="Result" Type="OutArgument(x:Int32)" />
</x:Members>

我们先创建工作流中使用的 输入、输出参数,主要是为了我们想自定数据或提供一些辅助方法到工作流中,

items:为自定义节点数据,主要是用来生成流程的数据(此数据为自己定义类的数据实体)

        public  ActivityBuilder CreateRule(string name,params RuleCondtionNode[] items)
{
var item = CreateProperty("Item",true); //生成输入参数
var Reulst = CreateProperty("Result",false);//生成输出参娄
ActivityBuilder wf = new ActivityBuilder();
wf.Name = name;
wf.Properties.Add(item);//把参数加入到创建的工作流中
wf.Properties.Add(Reulst);
wf.Implementation = CreateNodes(items);//开始用自定义的数据 创建流程节点
return wf;
}

创建输入、输出参数:  RuleModel:为我自定义要传入到工作流中使用的实体

        public  DynamicActivityProperty CreateProperty(string name,bool inOut)
{
var item = new DynamicActivityProperty();
item.Name = name;
item.Type = inOut? typeof(InArgument<RuleModel>): typeof(OutArgument<int>);//输入 OR 输出 是根据typeof 里的类型来决定的
return item;
}

创建流程节点:

   public Activity CreateNodes(params RuleCondtionNode[] model)
{
Sequence item = new Sequence();
for (int i = ; i < model.Length; i++)
{
item.Activities.Add(CreateNodeForType(model[i]));//把创建好的流程分去加入到活动中
}
return item;
} public InArgument<bool> CreateIf(string codeStr)
{
return new CSharpValue<bool>(codeStr); //创建返回结果为 bool类型的表达式 这里采用的是用C#代码 主要为 IF 提示条件使用
} public Assign<T> CreateAssign<T>(string name,string codeStr)
{
var item = new Assign<T>(); //这里创建的是 工作流中的 赋值操作 A=B
item.To = new ArgumentReference<T>(name); // A
item.Value = new CSharpValue<T>(codeStr); //B:这是创建的是 C#代码表达式 Value是一个 InArgument<T> 类型 所以其它类型也行 我只是为了灵活采用C#代码
return item;
}

通过上面几步可实现一个简单的工作流了,完整的代码这里并没有,但是关键性的代码都在。

下面到了生成 Xaml 字符串的环节:

 private static readonly string[] rfitem = new string[] { //这里是我们需要在Xaml中生成的命名空间 很重要 我们想住工作流中添加任务扩展类靠它了
"System",
"System.Collections.Generic",
"System.Linq",
"System.Text",
"QDRuleEngine.Model" //这是我自定义的类型
};
static RuleCreateHelper()
{
refList = rfitem.Select(c => new AssemblyReference() { AssemblyName = new System.Reflection.AssemblyName(c) }).ToList();//把命名空间的程序集加上
}
private static List<AssemblyReference> refList = new List<AssemblyReference>();//这里是Xaml中生成的 引用程序集 没有程序集大家懂的。生成好了也用不了 public string BuilderString(ActivityBuilder item)
{
TextExpression.SetNamespacesForImplementation(item, rfitem);//生成命名空间
TextExpression.SetReferencesForImplementation(item, refList);//生成引用程序集
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
System.Xaml.XamlWriter xw = ActivityXamlServices.CreateBuilderWriter(new XamlXmlWriter(tw, new XamlSchemaContext()));//交给它来生成Xaml
var xor = new XamlObjectReaderSettings(); try
{
XamlObjectReader reader = new XamlObjectReader(item, xor);
XamlServices.Transform(reader, xw);//通过此步我们就可以得到我们想要的 Xaml 字符串了
}
catch (Exception ex)
{ } return sb.ToString();//得到生成好的 Xaml 字符串 拿到这个字符串就可以 保存成Xaml工作流文件了
}

命名空间引用:

  <TextExpression.NamespacesForImplementation>
<sco:Collection x:TypeArguments="x:String">
<x:String>System</x:String>
<x:String>System.Collections.Generic</x:String>
<x:String>System.Linq</x:String>
<x:String>System.Text</x:String>
<x:String>QDRuleEngine.Model</x:String>
</sco:Collection>
</TextExpression.NamespacesForImplementation>

引用程序集:

  <TextExpression.ReferencesForImplementation>
<scg:List x:TypeArguments="AssemblyReference" Capacity="">
<AssemblyReference>System</AssemblyReference>
<AssemblyReference>System.Collections.Generic</AssemblyReference>
<AssemblyReference>System.Linq</AssemblyReference>
<AssemblyReference>System.Text</AssemblyReference>
<AssemblyReference>QDRuleEngine.Model</AssemblyReference>
</scg:List>
</TextExpression.ReferencesForImplementation>

我们生成好了想要的工作流后就是动态加载执行了:

       public  Activity LoadRule(string xmlStr)
{
Activity item = null;
try
{
item = ActivityXamlServices.Load(new StringReader(xmlStr),//拿到我们生成好的Xaml字符串 转换成工作流
new ActivityXamlServicesSettings()
{
CompileExpressions = true //如果在生成时采用了C#代码作为表达式时,必需把此值设为True 否则报错
});
}
catch (Exception ex)
{
item = null;
} return item;
} WorkflowInvoker item = new WorkflowInvoker(rule);// RuleModel model = new RuleModel(info, null, null, null, condition, new List<RuleRunLogInfo>());
//这是我们自定义的实体 刚才为此实体加了 命名空间 和 程序集 此实体我们可在工作流中的C#表达式中使用 例:A.MyFunc(123) 表达式为字符串 注意双引号 var result = item.Invoke(new Dictionary<string, object>()//传入我们需要的参数 执行工作流 如果 传入了工作流中没有定义的参数 会报错
{
["Item"] = model
});
Console.Write(result["Result"]); //得到执行入返回的结果

完整的工作流生成示例代码 http://pan.baidu.com/s/1gfl9ZpD

流程控制:

  <Sequence>
<If>
<If.Condition>
<InArgument x:TypeArguments="x:Boolean">
<mca:CSharpValue x:TypeArguments="x:Boolean">Item.Condition.GetValue&lt;Int32&gt;("sql_2017010306288856")&gt;</mca:CSharpValue>
</InArgument>
</If.Condition>
</If>
</Sequence>

流程控制

WF4.0以上使用代码完整自定义动态生成执行工作流Xaml文件的更多相关文章

  1. C#动态生成图书信息XML文件

    通过C#动态生成图书信息XML文件,下面有个不错的示例,需要的朋友可以参考下 通过C#动态生成图书信息XML文件(Books.xml),文件如下: 复制代码代码如下: <?xml version ...

  2. log4j2 不使用配置文件,动态生成logger对象

    大家平时使用Log4j一般都是在classpath下放置一个log4j的配置文件,比如log4j.xml,里面配置好Appenders和Loggers,但是前一阵想做某需求的时候,想要的效果是每一个任 ...

  3. MSChart使用之动态生成多个多行ChartArea

    前台代码: <asp:Chart ID=" > <Titles> <asp:Title Name="Title1" runat=" ...

  4. Python调用ansible API系列(四)动态生成hosts文件

    方法一:通过最原始的操作文件的方式 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 通过操作文件形式动态生成ansib ...

  5. cglib根据数据动态生成对象

    最近有个任务:根据查询SQL直接导出报表 实现关键是,怎么根据sql查询的数据动态生成对象列表,想到Cglib动态代理实现 废话少说,上代码: 定义动态生成Java Bean类: import jav ...

  6. java 动态生成SQL

    代码如下: /** * 动态生成SQ及SQL参数L * @param ve 接收到的消息的CHGLIST * @param paramList MQ消息中的SQL参数 * @param t 泛型对象 ...

  7. Log4j2 - 动态生成Appender

    功能需求 项目里将User分成了各个区域(domain),这些domain有个标志domainId,现在要求在打印日志的时候,不仅将所有User的日志都打印到日志文件logs/CNTCore.log中 ...

  8. jquery给动态生成的元素绑定事件,on函数

    首先先解释一下什么是动态生成的元素:动态生成的元素即我们用jquery的内部插入函数append()所生成的html代码.相对的也有静态生成的元素:即直接编写在页面的html代码. 下面通过例子来讲解 ...

  9. C#动态生成XML

    通过C#动态生成图书信息XML文件(Books.xml),文件如下: <?xml version="1.0" encoding="iso-8859-1"? ...

随机推荐

  1. Swift3.0 函数闭包与OC Block

    刚接触Swift,如有不对的点,欢迎指正.转载请说明出处 定义一个基本函数 //定义一个函数,接收一个字符串,返回一个String类型的值 func test(name:String) -> S ...

  2. JavaScript入门必备

    1.JavaScript和Java没有关系,JavaScript是一门(客服端)脚本语言,并且是一个解释性语言. 2.添加JavaScript的方法 (1)内联:通过<script>js代 ...

  3. MyBatis原始dao开发及问题总结(五)

    一.MyBatis原始Dao开发方式 1.原始dao开发需要程序员编写dao接口和dao接口实现类 编写UserDao接口:UserDao.java package codeRose.dao; pub ...

  4. 【前端调试手机页面】分享一款便捷的调试工具--spy-debugger

    spy-debugger  :  微信调试,各种WebView样式调试.手机浏览器的页面真机调试.便捷的远程调试手机页面.抓包工具,支持:HTTP/HTTPS,无需USB连接设备. github地址: ...

  5. Eclipse中将含有图片资源的项目打包成jar文件

    前言: 最近学了GUI编程和UDP协议,心血来潮想做一个局域网内的聊天软件,前期都还算顺利,直到后来将整个项目打包成jar文件时遇到了困难.如图: 自己设置的图标不见了,但是也没有默认的图标,说明图片 ...

  6. 重温Javascript(四)-函数

    函数 函数声明提升,在执行代码之前会先读取函数声明 sayHi(); function sayHi(){ alert("Hi!"); } 递归 arguments.callee是指 ...

  7. (一) 这就是所谓的Node.js------单线程,非阻塞,事件驱动

    Node.js 第一天笔记(V1) 一:Node.js到底是从何而来 2008年的秋天,一个名叫做Ryan Dahl(罗伊・达尔)的年轻人在玩了几年服务器编程之后,越发感到服务器高并发性能的瓶颈是一个 ...

  8. 关于laravel框架的跨域请求/jsonp请求的理解

    最近刚接触laravel框架,首先要写一个跨域的单点登录.被跨域的问题卡了两三天,主要是因为对跨域这快不了解,就在刚才有点茅塞顿开的感觉,我做一下大概整理,主要给一些刚接触摸不着头脑的看,哪里写得不对 ...

  9. java 基础知识六 字符串1

    java  基础知识六  字符串1 String 不是java的基本数据类型 String 不是java的基本数据类型 String 不是java的基本数据类型 字符串是是一个字符序列 1.创建 创建 ...

  10. IDEA 根据数据库表 生成 Model实体

    首先在 Idea中 配置数据源,测试ok(过程略) idea窗口中左下角是否 有显示Persistence 窗口  如果没有显示就要如下方法 添加显示: File - > Project Str ...