views:

1336

answers:

5

Hello StackOverflow gurus! 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 question, or rather 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.

I appreciate any insight and advice!

EDIT:

Thanks everyone for your input! 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.

+2  A: 

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.

John Saunders
I've messed with Service Factory a bit...it generates a TON of junk when you build. The visual contract designer is kind of neat, but the whole guidance package isn't really effective overall, I think. It would be nice if the contract designer was much lighter weight, similar, say, to the Entity Framework designer or something. Is there anything similar that isn't as heavy and intrusive?
jrista
I'd love to know what you mean by "heavy and intrusive" and a "ton of junk". I worked with it extensively, and customized it substantially, and I don't recall it generating anything that could be considered "junk". And I say that as someone who needed to get into the code generation logic and learn how it works.
John Saunders
Well, I didn't do any customization of the code generation. I messed with the visual contract designer a bunch, then finally told it to generate code. It ended up creating several nested solution folders, and nearly a dozen projects, a couple test projects, none of which was very useful to me. We have a very large, existing infrastructure, and I was hoping to just get some simple output: service interface, service implementation, data/message types. I didn't expect to get a dozen projects.
jrista
Ok, yeah, it does produce its own solution structure, which is one of the things I had to customize. I actually wound up with _more_ projects, but all in the right place. If you look in those projects, you'll find they do have the correct code generated. It's little or no different from what you would generate yourself, just broken up into multiple projects.
John Saunders
We can't have it generating projects...we already have the projects, we just need to get the generated code into them. Is it possible to achieve this with Service Factory? I would like to avoid a lot of customization of the guidance package if at all possible. And, ideally, it would be best if we could only generate the service contract and implementation that uses our existing DTO's.
jrista
What you may not realize is that some of the features of the SF are a lot easier to implement if you know where all the types are ahead of time. That's one reason why it wants to put all the data contracts into a single project, for instance. They also take care of all inter-project references, set up the code analysis settings correctly, etc. It's not a quick tool - it's more of a way of life.
John Saunders
Thanks for the input John. I'm looking more into SF to see what I can customize and tune. Having a visual designer for creating WSDL is pretty nice, and no other tool that I've seen yet has that.
jrista
I hope it helps. If there's anything else I can do for you on this, let me know. It's a fairly nice piece of code, an advanced example of how to use DSLs, GAT and GAX together. The DSL Toolkit itself is a good way, not only to generate code from a model instance, but it's also a good entry point to Visual Studio Extensibility.
John Saunders
+2  A: 

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

Marc Gravell
I actually explicitly need the ability to use different types at each end. One of the problems I am trying to solve is a build decouple. Right now, we have several domains that are dependent on each other, and they need to be more independent. Were looking to WCF to help us achieve that goal, as well as other core aspects of service-orientation. Our current architecture was designed from a very non-dotnet perspective (interestingly enough, it is primarily designed by java architects, not .net architects...you can imagine the disconnect.)
jrista
Protocol buffers look interesting. You mentioned there is a C# generator. What about a WSDL generator? One of the things I am looking for is the ability to start with WSDL, and generate everything from that, DTO's and all, on both sides of the wire.
jrista
protobuf-net supports different types at each end as long as they meet the contract (for exmaple, I have it running with LINQ-to-SQL entities at the server and svcutil proxy entities on the client in one example). No WSDL for protobuf-net, as there is no need for a second language.
Marc Gravell
We actually have .NET and Java systems here, and we also need to inter-operate with other systems that are part of our parent company, but written in possibly a wide variety of languages and platforms. I am not sure that protobuf will always be a viable option on both ends of the wire... Its contract language looks simple enough that I could write a WSDL/XSD generator from it...but is the custom protobuf serialization also a requirement?
jrista
Well; no. You could strip the protobuf-net bits and just use the DSL to generate the WCF proxies (easy to do - it is just an xslt), but that is missing the point of protocol buffers... Given that it is supported on Java, C++, Python and (separately) all of these: http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns - but the RPC stack (via WCF) is **not** standardised; that is implementation specific.
Marc Gravell
Gocha. Protocol buffers are basically an alternative to web services/WSDL/WS-* standards, if I understand you right. And more efficient given they use a standard binary serialization? Thanks for the input Marc.
jrista
@Marc, what about correcting that for the WCF problem of throwing exceptions in Dispose?
John Saunders
@jrista: yes, the binary serialization is standard; but there is no current "standard" RPC for this; there are a handful - including simply piggy-backing off WCF.
Marc Gravell
@John: indeed, that was a "minified" version; my standard implementation re-implements IDisposable, more like this: http://groups.google.co.uk/group/microsoft.public.dotnet.languages.csharp/msg/552663dfa6be9bf4
Marc Gravell
+1 for showing how to do it without svcutil.exe. thanks.
gWiz
+4  A: 

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

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

Cheeso
Thanks for the link, Chesso. This looks very promising. However, there does not appear to be a download on that CodePlex site. Any idea where I can download WCSF.blue?
jrista
I complained to the project owners and they told me they'd have a downloadable binary "real soon now". For now your option is to download the source and run "msbuild".
Cheeso
We are currently developing on .NET 3.5 SP1, with C# 3.0. This really does look promising. Thanks for the input! If nothing else better than this comes along before the bounty period ends, I think you have it bagged. :)
jrista
I didn't realize there *was* a bounty. heh. Wonder what I can spend all my points on!?! uh, what's that?...they're not worth anything? oh...
Cheeso
Actually a download was released about 3 hours ago. How cutting edge is that?
blowdart
I'm updating the answer accordingly.
Cheeso
A: 

The way we do this is described in this video:

http://perseus.franklins.net/dnrtvplayer/player.aspx?ShowNum=0103

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.

Shiraz Bhaiji
A: 

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.

Ray Mendonsa