快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

ag8只为非凡试玩:关于工作流(Workflow Foundation)的一些总结归纳BR1. 通过可视化的界面将流程设计与程序逻辑分离开来。BR2.业务逻辑的数据还是需要我们自己设计数据库保存以及维护的BR3. 一般一套工作流的解决方案需要包含哪些组件



着实,以我的体会,事情流(Workflow Foundation)从它一出生就褒贬不一。至少它确凿今朝看起来照样对照难用。在.NET 3.5以及之前的版本中,为了实现事情流,我们照样必要编写相称多的代码。

我感觉,WF给我们带来的主要有几点是值得懂得的

1. 经由过程可视化的界面将流程设计与法度榜样逻辑分分开来。

流程设计的可以尽管流程,他们不要知道怎么做。流程设计的职员可能(或者必然)不会用Visual Studio,他们可以应用一些简单的设计器对象。例如下面的这个小例子便是一个自力的法度榜样,上面包装了WF的设计器。结合自定义Aag8只为非凡试玩ctivity的设计,可以将营业逻辑暗藏起来。

2.营业逻辑的数据照样必要我们自己设计数据库保存以及掩护的

这是很多人疑心的,他们感觉既然有Workflow Foundation,就万事大年夜吉了。由于事情流实例确凿也稀有据,而且我们可以持久化将其保存起来嘛。

停!这不是一个精确的设法主见。事情流的持久化办事顾名思义,着实主如果为了给我们掩护长光阴事情的流程信息的(可以在余暇的时刻卸载,保存到数据库等)。

大年夜家应该这样理解,Workflow Foundation只是管流程的部分,它不管数据。

没错,它尽管流程。这有什么问题么,它管好这个就够了,而且确凿能帮很大年夜的忙,不是吗?

这样,我们就可以将留意力放在营业数据的治理,而不是流程状态的治理之类。

3. 一样平常一套事情流的办理规划必要包孕哪些组件

请留意上面选中的项目,我来解释一下

3.1 WorkflowLibrary 这个项目包孕了事情流设计,它是可视化设计的成果。下图是一个范例的审批流程

3.2 OrderApprovalEventType 这个项目包孕了事情流设计时可能会用到的一些接口和事故定义。为什么必要用事故呢?一样平常我们的流程假如必要等待用户干预,诸如审批之类的环境,就必要这样做,由于它可能不是急速发生的。

留意,接口要标记为ExternalDataExchange,事故参数必要承袭ExternalDataEventArgs,而且必须可序列化

3.3 Contracts 这个项目是标准的WCF合约定义,由于我们是分了办事器和客户真个,他们之间经由过程WCF通讯,包括创建流程,以及引发事故等等

3.4 Services,这便是详细实现的WCF办事,在这里可以启动事情流运行时,并且按照客户端指令做响应的工作。这里的代码是相称多的。

using System;

using System.Collections.Generic;

using System.Linq;

using Contracts;

using System.ServiceModel;

using System.Workflow.Runtime;

using OrderApprovalEventType;

using System.Workflow.Activities;

using System.Workflow.Runtime.Hosting;

using System.Workflow.Runtime.Tracking;

namespace Services

{

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]//只有一个实例

public class OrderService:IOrderService

{

//运行时

private WorkflowRuntime runtime = null;

//所有实例

private List instances = new List();

//本地办事

LocalService local = null;

public OrderService() {

runtime = new WorkflowRuntime();

//添加数据互换办事,可以引发事故

ExternalDataExchangeService svr = new ExternalDataExchangeService();

runtime.AddService(svr);

local = new LocalService();

svr.AddService(local);

//添加持久化办事,保存实例

//F:\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\zh-CHS这里会有脚本

var db = "server=(local);database=WorkflowFoundation;integrated security=true";

SqlWorkflowPersistenceService sqlsvc = new SqlWorkflowPersistenceService(db);

runtime.AddService(sqlsvc);

//添加跟踪办事,可以对办事进行诊断和调试

SqlTrackingService tracksvc = new SqlTrackingService(db);

runtime.AddService(tracksvc);

//绑定有关的事故

runtime.WorkflowStarted += new EventHandler(runtime_WorkflowStarted);

runtime.WorkflowCompleted += new EventHandler(runtime_WorkflowCompleted);

runtime.WorkflowCreated += new EventHandler(runtime_WorkflowCreated);

runtime.WorkflowAborted += new EventHandler(runtime_WorkflowAborted);

runtime.WorkflowTerminated += new EventHandler(runtime_WorkflowTerminated);

runtime.WorkflowUnloaded += new EventHandler(runtime_WorkflowUnloaded);

runtime.StartRuntime();//启动运行时

Console.WriteLine("事情流办事器已经筹备就绪");

//加载那些保存好的流程实例

foreach (var item in sqlsvc.GetAllWorkflows())

{

var instance =(WorkflowLibrary.Workflow1)runtime.GetWorkflow(item.WorkflowInstanceId).GetWorkflowDefinition();

instances.Add(

new WorkflowIntanceData()

{

Id = item.WorkflowInstanceId,

Amount = instance.Amount

});

}

}

void runtime_WorkflowUnloaded(object sender, WorkflowEventArgs e)

{

Console.WriteLine("光阴:{0},卸载流程:{1}", DateTime.Now, e.WorkflowInstance.InstanceId);

}

void runtime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)

{

Console.WriteLine("光阴:{0},终止流程:{1}", DateTime.Now, e.WorkflowInstance.InstanceId);

}

void runtime_WorkflowAborted(object sender, WorkflowEventArgs e)

{

Console.WriteLine("光阴:{0},中断流程:{1}", DateTime.Now, e.WorkflowInstance.InstanceId);

}

void runtime_WorkflowCreated(object sender, WorkflowEventArgs e)

{

Console.WriteLine("光阴:{0},创建流程:{1}", DateTime.Now, e.WorkflowInstance.InstanceId);

}

void runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)

{

var found = instances.FirstOrDefault(d => d.Id == e.WorkflowInstance.InstanceId);

if (found != null)

instances.Remove(found);

Console.WriteLine("光阴:{0},完成流程:{1}", DateTime.Now, e.WorkflowInstance.InstanceId);

}

void runtime_WorkflowStarted(object sender, WorkflowEventArgs e)

{

Console.WriteLine("光阴:{0},启动流程:{1}", DateTime.Now, e.WorkflowInstance.InstanceId);

}

#region IOrderService 成员

public void StartRequest(Guid id, int amount)

{

//筹备数据

var initParam =new Dictionarystring,object>();

initParam.Add("Amount",amount);

//创建实例

var instance = runtime.CreateWorkflow(

typeof(WorkflowLibrary.Workflow1),

initParam,

id);

//保存有关数据

instances.Add(

new WorkflowIntanceData(){

Id = id,

Amount = amount,

RequestEmployee="陈希章"

});

//启动实例

instance.Start();

}

public void ProcessRequest(Guid id, OrderApprovalEventType.ProcessResult result, string notes)

{

var args = new ProcessEventArgs(id);

args.Result = result;

args.Notes = notes;

//从聚拢中删除掉落有关的实例

var found = instances.FirstOrDefault(d => d.Id == id);

if (found != null)

instances.Remove(found);

local.RaiseEvent(args);//引发事故

}

public List GetWorkflowInstances()

{

return instances.Where(d => d.Amount >= 2000).ToList();

}

#endregion

#region IOrderService 成员

public void UnLoad(Guid id)

{

runtime.GetWorkflow(id).Unload();//要求开启MSDTC办事

}

#endregion

~OrderService() {

//析构的时刻将所有未完成的事情流实例保存起来

foreach (var item in runtime.GetLoadedWorkflows())

{

item.Unload();

}

}

public void UnloadAllInstances() {

foreach (var item in runtime.GetLoadedWorkflows())

{

item.Unload();

}

}

}

[Serializable]//这个必须标记为可序列化

internal class Loag8只为非凡试玩calService : ManagerEvent

{

#region ManagerEvent 成员

public event EventHandler

Process;

#endregion

internal void RaiseEvent(ProcessEventArgs e) {

//这里可能要更新数据库

if (Process != null)

Process(this, e);

}

}

}

留意:这里有一个所谓本地办事的观点,是要实现第二步的那个接口,并编写有关触发事故的代码

3.5 HostService 如上都筹备好之后,接下来便是经由过程必然的要领托管这些办事了。我们可以采纳Windows Service来托管

3.6 SimpleClient 着末当然少不了要有客户端界面来实现一些操作。我们这里应用了Windows Forms作为界面。

using System;

using System.Windows.Forms;

using System.ServiceModel;

using Contracts;

namespace SimpleClient

{

public partial class Form1 : Form

{

IOrderService proxy = null;

public Form1()

{

Initialag8只为非凡试玩izeComponent();

}

protected override void OnLoad(EventArgs e)

{

base.OnLoad(e);

ChannelFactory factory = new ChannelFactory(new BasicHttpBinding(), new EndpointAddress("http://localhost:8080/OrderService"));

proxy = factory.CreateChannel();

}

private ag8只为非凡试玩void btRequest_Click(object sender, EventArgs e)

{

int amount = int.Parse(txtAmount.Text);

proxy.StartRequest(Guid.NewGuid(), amount);

MessageBox.Show("已经提议了一个订单");

}

private void btGet_Click(object sender, EventArgs e)

{

dgvRequests.DataSource = proxy.GetWorkflowInstances();

}

private void dgvRequests_CellEnter(object sender, DataGridViewCellEventArgs e)

{

btOK.Enabled = btCancel.Enabled = true;

}

private void dgvRequests_CellLeave(object sender, DataGridViewCellEventArgs e)

{

//btOK.Enabled = btCancel.Enabled = false;

}

private void btOag8只为非凡试玩K_Click(object sender, EventArgs e)

{

var row = dgvRequests.Rows[dgvRequests.SelectedCells[0].RowIndex];

var id = (Guid)row.Cells[0].Value;

proxy.ProcessRequest(

id, OrderApprovalEventType.ProcessResult.Approval, txtNotes.Text);

}

private void btCancel_Click(object sender, EventArgs e)

{

var row = dgvRequests.Rows[dgvRequests.SelectedCells[0].RowIndex];

var id = (Guid)row.Cells[0].Value;

proxy.ProcessRequest(

id, OrderApprovalEventType.ProcessResult.Reject, txtNotes.Text);

}

private void btUnload_Click(object sender, EventArgs e)

{

var row = dgvRequests.Rows[dgvRequests.SelectedCells[0].RowIndex];

var id = (Guid)row.Cells[0].Value;

proxy.UnLoad(id);

}

}

}

这样,一套事情流办理规划就做好了。这个架构可以供很多同伙参考

别的,下面有几篇有关的文章可以参考进修

事情流内部事情道理(一)

http://blogs.msdn.com/cnflow/archive/2010/04/16/9996989.aspx

事情流内部事情道理(二)

http://blogs.msdn.com/cnflow/archive/2010/04/16/9996992.aspx

事情流内部事情道理(三)

http://blogs.msdn.com/cnflow/archive/2010/04/16/9996995.aspx

转自:http://www.cnblogs.com/chenxizhang/archive/2010/04/21/1716774.html

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: