代码之家  ›  专栏  ›  技术社区  ›  TrueWill

限制客户对工作流的了解

  •  0
  • TrueWill  · 技术社区  · 14 年前

    脚本:

    • .NET 4下的Windows Workflow Foundation(WF)
    • 作为WCF服务部署的工作流
    • 多个接收操作,所有操作都具有相同的参数
    • 操作名与活动名匹配
    • 使用SQL Server工作流持久性
    • (没有SharePoint)

    默认情况下,当您添加服务引用并生成代理时,工作流的知识会嵌入到客户端中。客户端知道哪些WCF方法可用。

    我想将工作流与客户机分离,本质上创建一个“通用”客户机,它可以处理与特定约定匹配的任何工作流。客户机将查询SQL实例存储以确定给定实例正在等待的活动/操作/书签(这已经是一个标准的列-ActiveBookmarks),然后将该选项呈现给用户。

    这样就可以更改工作流,而无需重新编译/重新部署客户端。有几个商业BPM系统是这样工作的;您可以添加新的人工客户机活动,它们会自动显示在客户机的工作队列中。一切都是动态可发现的。

    怎么能做到?是否需要使用Reflection.Emit动态生成代理?如果每个操作都使用不同的服务合同,会更容易吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Maurice    14 年前

    我在几个项目中都做过,效果很好。而且不需要使用反射,因为WCF已经准备好了所有必需的基础设施。

    例如,下面的代码将调用默认的工作流服务模板,您只需提供正确的URL即可。

    class Program
    {
        static void Main(string[] args)
        {
    
            var factory = new ChannelFactory<IMyService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:9199/Service1.xamlx"));
            var proxy = factory.CreateChannel();
            var response = proxy.GetData(new GetDataRequest() { Value = 42 });
            Console.WriteLine(response.Value);
            Console.ReadLine();
        }
    }
    
    [ServiceContract(Name = "IService")]
    interface IMyService
    {
        [OperationContract]
        GetDataResponse GetData(GetDataRequest request);
    }
    
    [MessageContract(IsWrapped = false)]
    class GetDataRequest
    {
        [MessageBodyMember(Name = "int", 
            Namespace = "http://schemas.microsoft.com/2003/10/Serialization/")]
        public int Value { get; set; }
    }
    
    [MessageContract(IsWrapped = false)]
    class GetDataResponse
    {
        [MessageBodyMember(Name = "string", 
            Namespace = "http://schemas.microsoft.com/2003/10/Serialization/")]
        public string Value { get; set; }
    }
    

    如果您需要更多的灵活性,您还可以创建一个带有类型消息的Service Enter和Out-Outlook,以及一个名为“*”的操作契约,您可以根据需要手工编写您的WCF消息。

    推荐文章