WF4:宿主No-Service 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

 

 

 

本文转自生鱼片博客园博客,原文链接:http://www.cnblogs.com/carysun/archive/2010/01/10/WorkflowHostingEndpoint.html,如需转载请自行联系原作者

相关文章
|
2月前
|
Java Shell Android开发
Rockchip系列之CAN 新增framework封装service+manager访问(3)
Rockchip系列之CAN 新增framework封装service+manager访问(3)
26 2
|
Kubernetes 负载均衡 网络协议
开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service
开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service
206 0
开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service
|
存储 数据可视化
SAP Gateway Service Builder 里 Project 的概念
SAP Gateway Service Builder 里 Project 的概念
88 0
SAP Gateway Service Builder 里 Project 的概念
使用SAP portal service创建Fiori Launchpad
使用SAP portal service创建Fiori Launchpad
118 0
使用SAP portal service创建Fiori Launchpad
使用C4C ABSL调用外部web service创建service request
使用C4C ABSL调用外部web service创建service request
|
前端开发 存储 网络协议
Service Fabric学习-从helloworld开始(无状态服务)
原先做服务器程序, 都是部署在xx云上, 也没理解云是个啥, 不就是个服务器(虚拟机)租赁商吗? 好吧, 其实这个是IaaS, 而接下来要学习的ServiceFabric(以下简称SF)是PaaS.  首先SF和Orleans类似, 都是基于actor模型, 然后编程方式也很像, 大概就是定义公开接口, 然后后端服务实现接口, 前端调用接口这样.
2072 0