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

  • 相关阅读:
    java基础部分的一些有意思的东西。
    antdvue按需加载插件babelpluginimport报错
    阿超的烦恼 javaScript篇
    .NET E F(Entity Framework)框架 DataBase First 和 Code First 简单用法。
    JQuery获得input ID相同但是type不同的方法
    gridview的删除,修改,数据绑定处理
    jgGrid数据格式
    Cannot read configuration file due to insufficient permissions
    Invoke action which type of result is JsonResult on controller from view using Ajax or geJSon
    Entity model数据库连接
  • 原文地址:https://www.cnblogs.com/carysun/p/WorkflowHostingEndpoint.html
Copyright © 2011-2022 走看看