使用WCF的契约优先SOA

时间:2009-06-26 03:25:53

标签: .net wcf soa contract-first

这个问题更多的是探索在实际情况下发现人们在社区中所做的事情,而不是特定目标问题。我已经对此进行了广泛的搜索,虽然我发现许多博客主张提出契约优先服务设计并且有一些评论支持它们,但我还没有找到关于实施与WCF合同优先的实用信息,优缺点在真实环境等方面这样做我最近对SOA进行了一些广泛的研究,主要是通过Thomas Erl的书籍,他提倡的主要概念之一是契约优先设计。

我的问题如下:

  1. 如何使用.NET和WCF实现契约优先服务设计?
  2. 除了svcutil之外还有其他工具可以从合同生成客户端和服务吗? (任何与VS集成的东西都是理想的)
  3. 您在合约优先设计和wCF方面遇到过哪些真实的专业人士?
  4. 您在合约优先设计和WCF方面遇到了什么现实利弊?
  5. 合同优先发展的一个主要问题似乎是工具。 Svcutil是我发现的唯一可以从契约中生成服务代码的东西,它有一些非常糟糕的输出。它的单个文件,充满了属性和代码生成工件,它基本上需要在合同更新时重新生成和替换。我更喜欢更好的方法,最好是不需要再生更换的方法。我甚至可以手动创建服务端合同,假设它在实际场景中是实用的。

    编辑:

    虽然WCSF解决了我的迫切需求,但了解Protocol BuffersService Factory都是有趣的工具,我相信这些工具将在未来帮助我。

5 个答案:

答案 0 :(得分:15)

WSCF提供了VS集成的契约优先工具。看看这个。 (免费)

截至7月6日,有一个带安装程序的二进制版本。

答案 1 :(得分:5)

我使用契约优先方法,通常(但并非总是)在每一端使用相同的类型表示。

实际上,要使用WCF,您不需要任何特殊代理等;您可以在两端使用常规.NET类型,而不是全部使用svcutil.exe 。获得工作服务就像在配置文件中添加“ABC”一样简单,并使用类似:

public sealed class WcfClient<T> : System.ServiceModel.ClientBase<T>
    where T : class
{
    public T Service { get { return base.Channel; } }
}

现在你可以使用:

using(var client = new WcfClient<IMyService>()) {
    int i = client.Service.SomeMethod("abc");
}

您在客户端(和服务器)拥有的只是您的IMyService界面。


其他工具; protobuf-net是Google的“协议缓冲区”API的一种实现,它具有用于以“合同优先”(和可移植/可互操作)方式描述数据和服务的DSL - 例如(.proto文件):

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}
message SearchResponse {
  repeated string result = 1; 
}
service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

protobuf-net工具(我维护)包括一个“protogen”实用程序,用于将此DSL转换为C#/ VB;其中一个选项(对于C#,至少 - 我需要检查VB)是发出一个完整的WCF代理实现(用你选择的同步或异步方法);与svcutil非常相似 - 但是(由于protobuf-net关系)它在操作契约中包含自定义[ProtoBehavior]属性,因此它使用protobuf-net序列化器而不是DataContractSerializer(更快更多)有效但不同)。

用于VS集成;我正在努力(proof)。

答案 2 :(得分:3)

我更喜欢契约优先发展。为此,我使用了Service Factory。它允许我生成服务和客户端代码而无需自定义。

通过自定义,我们还能够生成与Entity Framework对象相对应的数据传输对象,以及从一个对象转换为另一个的代码;自动记录异常;和服务的HTML文档。

这是Service Factory附带的代码分析规则的补充,它有助于防止开发人员通过选择不兼容的WCF选项来自我攻击。

答案 3 :(得分:2)

在WCF中,你在“契约优先”看起来有些多样性。您可以先执行“代码合同”,其中您的数据和服务合同表示为具有正确属性标记的.NET类型。您可以从WSDL开始并生成服务和数据协定,或者您可以从数据协定的XML模式开始,并将服务合同表示为代码。你走哪条路取决于合同的性质以及如何使用合同。

如果你正在为WSDL规范实现某些东西,那么来自WSDL的代码生成是显而易见的选择,并且从手工生成并不是一件大事。如果希望更改WSDL文件立即传播,可以从项目构建事件(或进入msbuild)触发生成。

如果您希望将现有架构(XSD)用作数据协定,或者希望以这种方式开发数据协定以便在其他平台中更容易地重用,则可以使用xsd.exe从架构生成类型(或第三方替代)。在这种情况下,您将在面向代码的服务合同中使用XML可序列化类型,如this :.

如果您是在.NET中自己开发客户端和服务器,并且您的客户可以获得合同程序集或者很乐意从服务元数据(例如WSDL)生成客户端,那么在代码中对合同进行建模是一种很棒的体验。使用“已知类型”方案,您可以在数据协定中支持继承模型,这可能非常强大。您可以通过直接引用客户端中的合同程序集来完全跳过生成客户端代码(如其他回复中所述)。它非常高效和优雅,但你需要意识到,如果你太过花哨,你可以创造互操作挑战。

答案 4 :(得分:0)

我们这样做的方式在此视频中描述:

http://www.dnrtv.com/default.aspx?showNum=103

我们的想法是不使用代码生成,因此我们避免在合同更改时需要重新生成代码。

然后合同是代码并且可以更改,如果客户端和服务器之间不匹配,它将显示在构建错误中。