使用 WCF 的契约优先 SOA
这个问题更多的是探索人们在社区中、在实际情况中所做的事情,而不是一个有针对性的问题。 我对此进行了相当广泛的搜索,虽然我发现很多博主都提倡契约优先的服务设计,并且有一些评论支持它们,但我还没有找到很多关于使用 WCF 实现契约优先的实用信息、优点和缺点最近,我主要通过 Thomas Erl 的书籍对 SOA 进行了一些广泛的研究,他提倡的主要概念之一是契约优先设计。
我的问题如下:
- 您如何使用 .NET 和 WCF 进行契约优先服务设计?
- 除了 svcutil 之外,还有其他工具可以从合约生成客户端和服务吗? (任何与 VS 集成的东西都是理想的)
- 您在契约优先设计和 wCF 方面遇到过哪些现实世界的专业人士?
- 您在契约优先设计和 WCF 方面遇到过哪些现实问题?
合同优先开发的主要问题之一似乎是工具。 Svcutil 是我发现的唯一可以从合约生成服务代码的东西,而且它的输出相当差。 它是单文件,充满属性和代码生成工件,并且基本上需要在合约更新时重新生成和替换。 我更喜欢更好的方法,最好是不需要重新生成的方法。 我什至可以手动创建服务端合约,假设它在现实场景中是实用的。
编辑:
This question is more of a probe to discover what people are doing in the community, in practical situations, than a specifically targeted question. I have searched pretty broadly about this, and while I have found a lot of bloggers advocating contract-first service design and some comments backing them up, I have yet to find much practical information about implementing contract-first with WCF, the pros and cons of doing so in a real-world environment, etc. I have recently done some extensive research into SOA, primarily through Thomas Erl's books, and one of the primary concepts he advocates is contract-first design.
My questions are as follows:
- How do you approach contract-first service design with .NET and WCF?
- Are there other tools besides svcutil that can generate both client and service from contract? (Anything that integrates with VS would be ideal)
- What real-world pros have you encountered with contract-first design and wCF?
- What real-world cons have you encountered with contract-first design and WCF?
One of the major problems with contract-first development seems to be tooling. Svcutil is the only thing I have found that can generate service code from a contract, and it has some pretty poor output. Its single-file, chock full of attributes and code-generation artifacts, and it basically needs to be regenerated and replaced any time the contract is updated. I would prefer a better approach, preferably something that doesn't require regen-replace. I'm fine with manually creating the service-side contract even, assuming it is practical in a real-world scenario.
EDIT:
While WCSF solved my immediate needs, learning about Protocol Buffers and Service Factory are both intriguing tools that I am sure will help me in the future.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我使用契约优先的方法,通常(但并非总是)在每一端使用相同的类型表示。
实际上,要使用 WCF,您不需要任何特殊的代理等; 您可以在两端使用常规 .NET 类型,而根本不使用
svcutil.exe
。 获得一个可用的服务非常简单,只需将“ABC”添加到配置文件中,然后使用类似以下内容:现在您可以使用:
客户端(和服务器)上拥有的就是您的
IMyService
接口。对于其他工具; protobuf-net 是 Google 的“协议缓冲区”API 的实现,它具有用于以“合约优先”(和可移植/可互操作)方式描述数据和服务的 DSL - 例如(.proto 文件):
protobuf-net工具(我维护的)包括一个“protogen”实用程序,用于将此 DSL 转换为 C#/VB; 其中一个选项(至少对于 C# - 我需要检查 VB)是发出完整的 WCF 代理实现(可以选择同步或异步方法); 与 svcutil 非常相似 - 但(由于 protobuf-net 关系)它包含操作契约上的自定义
[ProtoBehavior]
属性,以便它使用 protobuf-net 序列化器而不是DataContractSerializer
(更快、更高效,但有所不同)。用于VS集成; 我正在研究这一点(证明)。
I use a contract-first approach, generally (but not always) using the same type representation at each end.
Actually, to use WCF you don't need any special proxies etc; you can use your regular .NET types at both ends and not use
svcutil.exe
at all. Getting a working service is as simple as adding the "ABC" into the configuration file, and using something like:Now you can use:
and all you have at the client (and server) is your
IMyService
interface.For other tools; protobuf-net is an implementation of Google's "protocol buffers" API, which has a DSL for describing data and services in a "contract first" (and portable/interoperable) way - for example (a .proto file):
The protobuf-net tool (which I maintain) includes a "protogen" utility to transform this DSL into C#/VB; and one of the options (for C#, at least - I'd need to check VB) is to emit a full WCF proxy implementation (with your choice of sync or async methods); very similar to svcutil - but (due to the protobuf-net relationship) it includes the custom
[ProtoBehavior]
attribute on the operation-contracts so that it uses the protobuf-net serializer instead ofDataContractSerializer
(faster and more efficient, but different).For VS integration; I'm working on exactly that (proof).
我确实更喜欢合同优先的开发。 为此,我使用了 服务工厂。 它允许我无需定制即可生成服务和客户端代码。
通过定制,我们还能够生成与实体框架对象相对应的数据传输对象,以及从一个对象转换为另一个对象的代码; 自动记录异常情况; 以及服务的 HTML 文档。
这是服务工厂附带的代码分析规则的补充,有助于防止开发人员通过选择不兼容的 WCF 选项搬起石头砸自己的脚。
I do prefer contract-first development. I have used the Service Factory for this purpose. It has allowed me to generate both the service and the client code with no customization.
With customization, we were also able to generate Data Transfer Objects corresponding to Entity Framework objects, along with the code to translate from one to the other; automatic logging of exceptions; and HTML documentation of the services.
This is in addition to the code analysis rules that come with the Service Factory, which help prevent a developer from shooting himself in the foot by choosing incompatible WCF options.
在 WCF 中,“契约优先”的表现形式存在一些差异。 您可以先执行“代码契约”,其中您的数据和服务契约将表示为具有正确属性标记的 .NET 类型。 您可以从 WSDL 开始并生成服务和数据契约,也可以从数据契约的 XML 模式开始,并将服务契约表示为代码。 你走哪条路实际上取决于合同的性质以及它将如何使用。
如果您要根据 WSDL 规范实现某些内容,那么从 WSDL 生成代码是显而易见的选择,并且手动生成并不是什么大问题。 如果您希望立即传播对 WSDL 文件的更改,则可以从项目构建事件(或进入 msbuild)触发生成。
如果您希望将现有架构 (XSD) 用作数据协定,或者更喜欢以这种方式开发数据协定以便更轻松地在其他平台中重用,则可以使用 xsd.exe(或第三种方法)从架构生成类型党的替代方案)。 在这种情况下,您可以在面向代码的服务合同中使用 XML 可序列化类型,例如
如果您自己在 .NET 中开发客户端和服务器,并且您的客户端可以获取您的契约程序集或者很乐意从服务元数据(例如 WSDL)生成客户端,那么在代码中对契约进行建模是一种很棒的体验。 使用“已知类型”方案,您可以在数据协定中支持继承模型,这非常强大。 您可以通过直接引用客户端中的合约程序集来完全跳过生成客户端代码(如其他回复中提到的)。 它非常高效且优雅,但您需要意识到,如果您过于花哨,可能会带来互操作挑战。
In WCF, you have some diversity in what 'contract-first' looks like. You can do a 'code contract first' where your data and service contracts are expressed as .NET types with the right attribute markup. You can start with WSDL and generate the service and data contracts, or you can start with XML schema for your data contract, and express the service contract as code. Which way you go really depends on the nature of the contract and how it will be used.
If you're implementing something to a WSDL spec, code gen from WSDL is the obvious choice, and generating from hand is not such a big deal. You could trigger generation from a project build event (or get into msbuild) if you want changes to the WSDL file to propagate immediately.
If you have existing schema (XSD) that you want to use as a data contract, or prefer to develop your data contract that way for easier re-use in other platforms, you can generate types from schema using xsd.exe (or a 3rd party alternative). In this case, you would use your XML-serializable types in your code-oriented service contract like this: .
If you're developing the clients and servers yourself in .NET, and your clients can either get your contract assemblies or are happy generating clients from service metadata (e.g. WSDL), modeling your contracts in code is a great experience. Using the "known types" scheme, you can support inheritance models in your data contract, which can be very powerful. You can skip generating client code entirely (as mentioned in other replies) by directly referencing the contract assembly in your client. It's very productive and elegant, but you need to be aware that you can create interop challenges if you get too fancy.
此视频描述了我们执行此操作的方式:
http://www.dnrtv.com /default.aspx?showNum=103
这个想法是我们不使用代码生成,因此我们避免在合约更改时需要重新生成代码。
然后合约以代码形式存在并且可以更改,如果客户端和服务器之间不匹配,它将显示在构建错误中。
The way we do this is described in this video:
http://www.dnrtv.com/default.aspx?showNum=103
The idea is that we do not use code generation, we therefore avoid needing to regenerate code when the contract changes.
The contract is then in code and can be changed, if there is a mismatch between the client and the server it will show up in a build error.
WSCF 提供了一个具有 VS 集成的合同优先工具。 一探究竟。 (免费)
自 7 月 6 日起,将推出带有安装程序的二进制版本。
WSCF provides a contract-first tool with VS integration. Checkitout. (free)
As of July 6th, there's a binary release with a setup program.