zoukankan      html  css  js  c++  java
  • WF4:宿主NoService Workflow

    我们在使用工作流服务时,一般会在工作流设计中使用Receive等消息活动,然后使用WorkflowServiceHost进行宿主,如果没有Receive活动,工作流就无法接受发送来的消息,这个时候我们可以使用WorkflowHostingEndpoint类:

    image

    要宿主一个没有服务的工作流,需要继承WorkflowHostingEndpoint并重写OnGetInstanceId,OnGetCreationContext,OnResolveBookmark。首先我们要声明一个服务契约,该契约包含一个创建新实例的服务操作,这个操作要传一个IDictionary<string,object>参数,这个契约隐式被WorkflowHostingEndpoint实现。当宿主这个工作流时,使用WorkflowServiceHost的AddServiceEndpoint方法添加。下面举例说明:

    1.下面是项目结构:

    clip_image002

    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.工作流设计如下:

    clip_image004 

    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.结果如下:

    clip_image006

  • 相关阅读:
    (73)C# 扩展方法
    网络
    (十九)守护进程
    (十二)函数返回局部变量
    (十八)WireShark 过滤语法
    (十七)linux网络命令 vconfig ifconfig
    (十六)getsockname()
    (十五)ioctl、ifreq、ifconf
    (十四)UDP协议的两个主要方法sendto和recvfrom详解
    (十三)Packet socket 和 sockaddr_ll
  • 原文地址:https://www.cnblogs.com/carysun/p/WorkflowHostingEndpoint.html
Copyright © 2011-2022 走看看