using System; using System.Threading; using System.Windows.Forms; using System.Workflow.Runtime; using System.Workflow.Activities; namespace Microsoft.Samples.Workflow.Communication.HostCommunication { // Class defines the message passed between the local service and the workflow [Serializable] internal class VotingServiceEventArgs : ExternalDataEventArgs { private string aliasValue; public VotingServiceEventArgs(Guid instanceID, string alias) : base(instanceID) { this.aliasValue = alias; } public string Alias { get { return this.aliasValue; } } } // Workflow communication interface which defines the contract // between a local service and a workflow [ExternalDataExchange] internal interface IVotingService { event EventHandler<VotingServiceEventArgs> ApprovedProposal; event EventHandler<VotingServiceEventArgs> RejectedProposal; void CreateBallot(string alias); } // Local service that implements the contract on the host side // i.e. it implements the methods and calls the events, which are // implemented by the workflow internal class VotingServiceImpl : IVotingService { public event EventHandler<VotingServiceEventArgs> ApprovedProposal; public event EventHandler<VotingServiceEventArgs> RejectedProposal; // Called by the workflow to create a new ballot, this method // creates a new thread which shows a voting dialog to the user public void CreateBallot(string alias) { Console.WriteLine("Ballot created for {0}.", alias); ShowVotingDialog(new VotingServiceEventArgs(WorkflowEnvironment.WorkflowInstanceId, alias)); } public void ShowVotingDialog(VotingServiceEventArgs votingEventArgs) { DialogResult result; string alias = votingEventArgs.Alias; // Show the voting dialog to the user and depending on the response // raise the ApproveProposal or RejectProposal event back to the workflow result = MessageBox.Show(string.Format("Approve Proposal, {0}?", alias), string.Format("{0} Ballot", alias), MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { EventHandler<VotingServiceEventArgs> approvedProposal = this.ApprovedProposal; if (approvedProposal != null) approvedProposal(null, votingEventArgs); } else { EventHandler<VotingServiceEventArgs> rejectedProposal = this.RejectedProposal; if (rejectedProposal != null) rejectedProposal(null, votingEventArgs); } } } }
在这个文件中首先定义了interface IVotingService,那么这个接口的作用是什么呢?接口定义了在工作流和本地交互时,使用的数据或者是函数,接口中定义的event可能是直接在接口中定义的或者是在workflow中定义的。
event EventHandler<VotingServiceEventArgs> ApprovedProposal;
event EventHandler<VotingServiceEventArgs> RejectedProposal;
void CreateBallot(string alias);
然后在这个文件中定义了一个实现类,将上面的接口实现,interface只是在说我能够干什么?但是实现类却是真正工作的类(说白了就是实际的worker)。
internal class VotingServiceImpl : IVotingService { public event EventHandler<VotingServiceEventArgs> ApprovedProposal; public event EventHandler<VotingServiceEventArgs> RejectedProposal; // Called by the workflow to create a new ballot, this method // creates a new thread which shows a voting dialog to the user public void CreateBallot(string alias) { Console.WriteLine("Ballot created for {0}.", alias); ShowVotingDialog(new VotingServiceEventArgs(WorkflowEnvironment.WorkflowInstanceId, alias)); } public void ShowVotingDialog(VotingServiceEventArgs votingEventArgs) { DialogResult result; string alias = votingEventArgs.Alias; // Show the voting dialog to the user and depending on the response // raise the ApproveProposal or RejectProposal event back to the workflow result = MessageBox.Show(string.Format("Approve Proposal, {0}?", alias), string.Format("{0} Ballot", alias), MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { EventHandler<VotingServiceEventArgs> approvedProposal = this.ApprovedProposal; if (approvedProposal != null) approvedProposal(null, votingEventArgs); } else { EventHandler<VotingServiceEventArgs> rejectedProposal = this.RejectedProposal; if (rejectedProposal != null) rejectedProposal(null, votingEventArgs); } } }
所以说整个的过程是这样的:
1.首先需要定义一个接口,主要适用于workflow和本地服务通信使用。
[ExternalDataExchange] internal interface IVotingService { event EventHandler<VotingServiceEventArgs> ApprovedProposal; event EventHandler<VotingServiceEventArgs> RejectedProposal; void CreateBallot(string alias); }
2.定义一个实现类,实现接口中定义的方法。
3.最工作流中使用HandleExternalEventActivity活动时,该活动可以invoke一个函数,当特定的外部事件触发时,调用这个invoke的函数。