Contract-First SOA with WCF

时间秒杀一切 提交于 2019-12-03 04:30:43

问题


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:

  1. How do you approach contract-first service design with .NET and WCF?
  2. Are there other tools besides svcutil that can generate both client and service from contract? (Anything that integrates with VS would be ideal)
  3. What real-world pros have you encountered with contract-first design and wCF?
  4. 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.


回答1:


WSCF provides a contract-first tool with VS integration. Checkitout. (free)

As of July 6th, there's a binary release with a setup program.




回答2:


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:

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

Now you can use:

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

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):

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);
}

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 of DataContractSerializer (faster and more efficient, but different).

For VS integration; I'm working on exactly that (proof).




回答3:


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.




回答4:


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.




回答5:


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.



来源:https://stackoverflow.com/questions/1047161/contract-first-soa-with-wcf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!