What I want to deal with here today is how a developer who believes in the very one approach to service and Web service design, can also use and embrace it with Indigo - or at least thoroughly understand any implications.
Until now, I have never written much about code generation from XSD and WSDL for the ASMX (or WSE) stacks. Maybe this would make a nice in-depth hardcore article for MSDN. But now with the rise of Indigo, I think people should see the light of the extremely clever and powerful Indigo platform. Indigo has not only the overall cool and sexy ServiceModel programming model which gets manifested at the surface at least by a number of .NET attributes. No.
Indigo also has (although currently still a bit rough) a powerful means to transform your XSD and WSDL and Policy metadata into a CLS-compliant representation. Yes, sure. There is a command line tool called svcutil.exe. But I intend to dive a bit deeper and show how the guts of such a tool work. Using the following code you can easily imagine how you can build your own tools (if you are an alien called 'plumber' or 'tool vendor') in order to provide some functionality for schema-based contract-first design and development which serves Indigo as the runtime. Obviously, this is nothing more than some demo code.
public static void ImportMetadataAndGenerateCode() { WsdlImporter importer = new WsdlImporter();
// Load metadata documents from current directory // XSDs foreach(string xsdFile in Directory.GetFiles(".", "*.xsd", SearchOption.TopDirectoryOnly)) { importer.XmlSchemas.Add(System.Xml.Schema.XmlSchema.Read(File.OpenRead(xsdFile), null)); }
// Policies foreach (string policyFile in Directory.GetFiles(".", "*.wsp", SearchOption.TopDirectoryOnly)) { XmlDocument doc = new XmlDocument(); doc.Load(File.OpenRead(policyFile)); importer.Policies.Add(doc.DocumentElement); }
ServiceContractGenerator generator = new ServiceContractGenerator();
// Generate code from contracts foreach (ContractDescription contract in xlator.ImportAllContracts()) { generator.GenerateServiceContractType(contract); }
// Here we have the abstract CLS CodeDom in 'our hands'... (in generator.TargetCompileUnit) using (StreamWriter writer = new StreamWriter(File.Create("firststeps.cs"))) { new Microsoft.CSharp.CSharpCodeProvider().GenerateCodeFromCompileUnit( generator.TargetCompileUnit, writer, new System.CodeDom.Compiler.CodeGeneratorOptions()); } }
Compared to today's available APIs when it comes to code generation based on metadata, the new Indigo API is much more powerful, feature-rich, and - most important to me - elegant to program. Any of them, whether old or new, are spitting out a CodeDom tree representation. This is perfect for applying code enhancements through a decorator pattern-oriented approach. Once you have the CodeDom in place, you can literally do anything with it. Note: AFAIK, WSE has no official, 'native' approach to get at the code/CodeDom from any XSD and/or WSDL. At least, I could not manage to hack it up in a reasonable amount of time.
Voila. This is the very first rough starting point for adding Indigo code-gen support to tools like WSCF. Sorry for no square brackets being present in above's snippet ;)
So, this is just one small piece of the big, big world of Indigo. Maybe next time, we will dive again into the deep areas of distributed applications programmer's new baby... there is enough to cover for everybody.