程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WF4:宿主No-Service Workflow

WF4:宿主No-Service Workflow

編輯:關於.NET

我們在使用工作流服務時,一般會在工作流設計中使用Receive等消息活動,然後使用WorkflowServiceHost進行宿主,如果沒有 Receive活動,工作流就無法接受發送來的消息,這個時候我們可以使用WorkflowHostingEndpoint類:

要宿主一個沒有服務的工作流,需要繼承WorkflowHostingEndpoint並重寫 OnGetInstanceId,OnGetCreationContext,OnResolveBookmark。首先我們要聲明一個服務契約,該契約包含一個創建新實例的服務操作,這個操作要傳一個IDictionary<string,object>參數,這個契約隱式被 WorkflowHostingEndpoint實現。當宿主這個工作流時,使用WorkflowServiceHost的 AddServiceEndpoint方法添加。下面舉例說明:

1.下面是項目結構:

2.首先定義服務契約,如下:

[ServiceContract(Name = "IWorkflowCreation")]
public interface IWorkflowCreation
{
         [OperationContract(Name = "Create")]
         Guid Create(IDictionary<string, object> inputs);
         [OperationContract(Name = "CreateWithInstanceId", IsOneWay = true)]
         void CreateWithInstanceId(Guid instanceId, IDictionary<string, object> inputs);
         [OperationContract(Name = "ResumeBookmark", IsOneWay = true)]
         void ResumeBookmark(Guid instanceId, string bookmarkName, string message);
}

3.下面是ResumeBookmarkEndpoint的實現:

namespace CaryCommon
{
     public class ResumeBookmarkEndpoint : WorkflowHostingEndpoint
     {
         public ResumeBookmarkEndpoint(Binding binding, EndpointAddress address)
             : base(typeof(IWorkflowCreation), binding, address)
         {
         }
         protected override Guid OnGetInstanceId(object[] inputs, OperationContext operationContext)
         {
             if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))
             {
                 return Guid.Empty;
             }
             else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId") ||
                     operationContext.IncomingMessageHeaders.Action.EndsWith("ResumeBookmark"))
             {
                 return (Guid)inputs[0];
             }
             else
             {
                 throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);
             }
         }
         protected override WorkflowCreationContext OnGetCreationContext(object[] inputs, OperationContext operationContext, Guid instanceId, WorkflowHostingResponseContext responseContext)
         {
             WorkflowCreationContext creationContext = new WorkflowCreationContext();
             if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))
             {
                 Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];
                 if (arguments != null && arguments.Count > 0)
                 {
                     foreach (KeyValuePair<string, object> pair in arguments)
                     {
                         creationContext.WorkflowArguments.Add(pair.Key, pair.Value);
                     }
                 }
                 responseContext.SendResponse(instanceId, null);
             }
             else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId"))
             {
                 Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];
                 if (arguments != null && arguments.Count > 0)
                 {
                     foreach (KeyValuePair<string, object> pair in arguments)
                     {
                         creationContext.WorkflowArguments.Add(pair.Key, pair.Value);
                     }
                 }
             }
             else
             {
                 throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);
             }
             return creationContext;
         }
         protected override System.Activities.Bookmark OnResolveBookmark(object[] inputs, OperationContext operationContext, WorkflowHostingResponseContext responseContext, out object value)
         {
             Bookmark bookmark = null;
             value = null;
             if (operationContext.IncomingMessageHeaders.Action.EndsWith("ResumeBookmark"))
             {
                 bookmark = new Bookmark((string)inputs[1]);
                 value = (string)inputs[2];
             }
             else
             {
                 throw new NotImplementedException(operationContext.IncomingMessageHeaders.Action);
             }
             return bookmark;
         }
     }
    }

4.下面完成工作流,首先定義一個自定義活動如下:

namespace CaryHost
{
     public sealed class CaryActivity<T> : NativeActivity<T>
     {
         public string BookmarkName { get; set; }
         protected override bool CanInduceIdle
         {
             get { return true; }
         }
         protected override void Execute(NativeActivityContext context)
         {
             context.CreateBookmark(BookmarkName, new BookmarkCallback(OnBookmarkCallback));
         }
         void OnBookmarkCallback(NativeActivityContext context, Bookmark bookmark, object state)
         {
             this.Result.Set(context, (T)state);
         }
     }
}

5.工作流設計如下:

6.服務端宿主程序如下:

namespace CaryHost
{
     class Program
     {
         static void Main(string[] args)
         {
             WorkflowServiceHost host = null;
             try
             {
                 host = new WorkflowServiceHost(new Workflow1(), new Uri("http://localhost"));
                 ResumeBookmarkEndpoint endpoint = new ResumeBookmarkEndpoint(new BasicHttpBinding(),
                     new EndpointAddress(new Uri("http://localhost/CaryService1.xaml")));
                 host.AddServiceEndpoint(endpoint);
                 host.Open();
                 Console.WriteLine("Host Started:"+endpoint.Address);
                 Console.ReadLine();
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex);
             }
             finally
             {
                 if (host != null)
                 {
                     host.Close();
                 }
             }
         }
     }
}

7.客戶端調用如下:

namespace CaryClient
{
     class Program
     {
         static void Main(string[] args)
         {
             ResumeBookmarkEndpoint endpoint = new ResumeBookmarkEndpoint(new BasicHttpBinding(),
                  new EndpointAddress(new Uri("http://localhost/CaryService1.xaml")));
             IWorkflowCreation client = new ChannelFactory<IWorkflowCreation>(endpoint.Binding, endpoint.Address).CreateChannel();
             Guid id = client.Create(null);
             Console.WriteLine("WorkflowApplication {0} Created", id);
             client.ResumeBookmark(id, "cary", "Hello Wold!");
         }
     }
}

8.結果如下:

出處:http://carysun.cnblogs.com/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved