情景:
默认情况下,当您添加服务引用并生成代理时,工作流的知识将嵌入到客户端中。客户端知道可用的WCF方法。
我希望将工作流与客户端分离,实际上创建了一个“通用”客户端,可以使用符合某些约定的任何工作流。客户端将查询SQL实例存储以确定给定实例正在等待的活动/操作/书签(这已经是标准列 - ActiveBookmarks),然后将该选择呈现给用户。
这样可以更改工作流,而无需重新编译/重新部署客户端。一些商业BPM系统以这种方式工作;您可以添加新的人工客户端活动,它们会自动显示在客户端的工作队列中。一切都是动态可发现的。
如何做到这一点?是否需要使用Reflection.Emit动态生成代理?如果每个操作使用不同的服务合同会更容易吗?
答案 0 :(得分:1)
我在几个项目中完成了这项工作,它运作得很好。并且不需要使用Reflection.Emit,因为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; }
}
如果您需要更大的灵活性,您还可以创建一个ServiceIntered类型为Message in和out,以及一个带有Name =“*”的OperationContract,您可以根据需要手动创建WCF消息。