Usually, I am very much a strict SOA advocate. I really do believe in the principles of having loosely coupled, interface-based, self-contained services. But, that doesn’t mean that you’re not allowed to cut some corners once in awhile!
One of the problems with doing SOA based development in .NET is the more or less lousy support for true contract-first development in Visual Studio. The main issue is the fact that the XSD-generated classes you get from XSD.exe and WSDL.exe really suck. It is really easy to expose stuff as web services, but if you want to consume the very same services (or other services for that matter) you’re suddenly left with very basic support. It can be very annoying when you’ve spent all that time building a set of custom DTO classes using generic collections, properties etc and you realize that on the client they show up as empty shells with fixed-size arrays and public fields*.
So, what’s the solution then? Well, why not share BOTH schema AND class? Basically, what you do is that you make sure that the service CAN be used without any class knowledge (i.e. it is still exposed as a proper web service), but you let the client have the option of using the same DTO classes as the service!
In the previous version of .NET Framework, this meant doing a lot of manual changes to the WSDL-generated proxy classes. But with .NET Framework 2.0, Microsoft introduced the concept of “SchemaImporterExtensions”. Basically, you can write your own extension to XSD.exe and WSDL.exe to tell them to use your own DTO classes instead of generating them from scratch.
I’ve been working on a generic version of such an extension, but today I ran into this article from Microsoft Belgium that explains how to do just that. I’ll probably still do my own version (which I think will use a web service to get the mappings between service classes and clr classes), but the article explains the process very well. I wonder why this one hasn’t made the msdn homepage..?
* I know, in .NET Framework 2.0 you actually can make it produce properties, but those annoying arrays still remain.