Contract First and XSDObjectGen

I have been a fan of the concept of "Contract First" development, particularly where XML - based messages can encapsulate the data. This works not only for webservices, but for most any type of business object. The general idea is that if you can "Schematize" the objects at the message level, your customers or partners can get a copy of the schema and begin their part of the work about consuming your stuff even before you write any code.

This concept has not been lost on the folks at Microsoft. Not only have they incorporated the Application Connection Designer in VS.NET 2005 Team System, there has been significant work along these lines by some of the XML and webServices luminaries such as Christian Weyer and others. The MS XML Team Blog is another good place to start for resources and links.

Aaron Skonnard has a series he is doing on this at MSDN.

Enter XSDObjectGen from Colin Cole and Dan Rogers at Microsoft. This is a big step in the right direction, because it really fills in a lot of the missing links between Contract First (schema) and Code When? (your classes). Developers who are building applications that use XML based messaging need tools to "Start with the Schema" as the modelling language, and be able to quickly and accurately generate the code implementations that allow them to stay in the Object Oriented Programming World they are comfortable in.

Feed it your schema(s) and get back XSD.EXE - style classes - but on steroids! Everything you need (well, almost everything). Since the generated code consists of ordinary classes, you can even choose to ignore the fact that XML is even involved and simply use them as, well -- classes!

XSDObjectGen produces a new Project Type in VIsual Studio.NET - "XSDObjectGenerator" which uses the new library as a Visual Studio.NET wizard, making the process almost a no-brainer. Or, you can choose to use it on the command line and generate your classes "by hand". Either way, you get a lot for your trouble, including support for XML schema constructs, Enumerator and Collection behavior, a programming model that actually matches the orginating Schema, automatic subclass construction, and much more including a "MakeSchemaCompliant" method that addresses one of the shortcomings with this technique so that any required fields you haven't populated will be filled with at least default (empty) values. You also get depth-wise traversal events that you can hook. In short, if you can write a schema, which you can do very easily in the Visual Studio .NET XSD Schema Designer, you are gonna get a whole bunch of very usable code for your effort!

For Webservices, this thing is a dream - the generated sample classes are attributed to work well in document literal WSDL contracts, and you can directly use the generated classes as method arguments and return types in webservice method bodies. It even supports XMLInclude if your schema is in multiple "pieces" (only one level deep, however).

I have only one regret at this point: This thing would have saved me some 10 to 15 hours of tedious coding against somebody's industry spec schemas, had I found it two weeks earlier! Highly recommended.

NOTE: for those seeking a robust JAXB - style Schema Compiler for .NET, look up "DINGO" on Sourceforge.net Snippet:

"Dingo is a pluggable Schema Compiler for .NET and will generate C# code. The goal is to provide a simple way to generate Domain Objects. .NET XSD currently only generates Data Objects. Dingo can delegate code generation with high granularity."

N.B. Fellow MVP Daniel Cazzulino, who never ceases to amaze me because his batteries never seem to run down, is also working with a similar idea for VS.NET as an add-in, here.

Comments

  1. Peter, I completely agree with you about XSDObjectGen, it Rules!
    I'm developing an interop project, where we consume Java WebServices form a .Net client interface.
    We decided to do a contract-first approach, specifying the schemas up-front to ensure data type compatibility beteen Java and .Net.
    It worked nicely, for Java we are using Castor.
    Only one thing though, I'm unsing version 1.3.6 of XSDObjectGen. There's a new version available in MS Website, but has a pitfall. With the version I'm using, you can batch the generation and specify that any imported/included schema to be generated in a separate class. With the new version, it PROMPTS you for a correct namespace when generating the classes. I didn't find a way to workaround this problem, so I'm sticking with the old version.
    My email is: fabiangoncalves@hotmail.com.

    ReplyDelete
  2. Interesting. Can't you just physically include the actual targets of the includes into one schema? You might want to give the authors feedback on this and see what they have to say.

    ReplyDelete
  3. thanks for mentioning Dingo. Every now and then I google for Dingo to see who is using it and your blog showed up. I hope more people use Dingo, so it can continue to get better. I plan to implement support for other languages like XMI, RelaxNG and Sql in the future.

    ReplyDelete
  4. You're welcome! I was very impressed by your work. It shows a depth of understanding that is not neccessarily present in some of the other offerings in this important area. Keep up the good work!

    ReplyDelete
  5. Anonymous1:05 PM

    I had the same issue with the XSDObjectGen. I had it working great withthe older version, but then I "upgraded"....not so good. :( I tried Dingo, but it was not generating code using imports. I did not see an error in the log or on the DOS window.

    Oh well, I guess I will stick with the older version of XSDObjectGen.

    Paul

    ReplyDelete
  6. Anonymous1:43 PM

    I got a reply back from Dan Rodgers. This is what he said.

    The command line prompts for identifying the namespaces is a result of finding xs:import directives in your schemas. For each imported XML namespace, a corresponding .NET namespace that is different than the top level .NET assembly namespace is required. The change was introduced in 1.4.1 in order to be able to handle imported schemas that have global element name collisions.

    What you need to do is respond to those prompts with the appropriate information (for each prompt, supply a unique .NET namespace name). These will then be inserted into the generated code.

    If you were previously automating the generation of the code in a script, or as a pre-compile statement in a tool such as Visual studio, you'll have to make adjustments. The tool, a sample code generator, was not intended to be used as a precompiler. The best practice for this tool is to generate your code, make any changes you want, and use it as source code if you like the code that is output. Once the code is generated, try and avoid regenerating it - as any changes you made will be lost.

    ReplyDelete
  7. Anonymous9:11 PM

    The fear of regeneration should hopefully now be lessened with a little discipline, and using partial classes.
    Put all the extra coding into another partial class, then you can regenerate to your hearts content.
    This technique is very handy for contract first, as during the dev stage, there is always something missed out, and the schema needs "tweaking". So this helps reduce it.
    Thanks .NET 2.0.
    Yes, it does mean you have to like the code that the tool generates...

    ReplyDelete
  8. Thanks for the nice comments folks.

    ReplyDelete
  9. Anonymous11:52 AM

    XSDObjectGen is awesome. However, I would like to use the generated class in a Web Service but am a little confused on the ramifications of doing so if the consumer is -- say -- a Java client. Would this be a problem?

    ReplyDelete
  10. The only issues you might have using a class generated via XSDObjectGen with a JAVA client are the same ones you would have with any webservice and a JAVA Client. Namely, whether the JAVA Client is capable of interpreting the generated WSDL contract from the service.

    ReplyDelete
  11. I would have liked to get partial classes as output from XSDObjectGen, as we used to get from XSD.exe. But as I used it, the generated classes are not partial classes. Am I missing something what shall do the trick? Obviously I do not want to manually edit the generated code, as I have too many classes. Thanks for all the helps.

    ReplyDelete
  12. I would have liked to get partial classes as output from XSDObjectGen, as it is the case from XSD.exe. But as I used XSDObjectGen, the generated classes were not partial classes. Am I missing something what shall do the trick? Obviously I do not want to manually edit the generated code, as I have too many classes. Thanks for all the helps.

    ReplyDelete
  13. Anonymous2:13 PM

    Hey Folks. Saw this blog. This is Colin Cole, co-creator of the xsdobjectgen tool. Nice blog! BTW, and updated version AND the source code is now available on CodePlex.com at http://www.codeplex.com/IVC . The codegenerator and source code was included as part of the IvcAcordAccelerator in the Utilities folder. So download the IvcAcordAccelerator on the Releases page, and you can grab the new code generator and source from the Utilities folder in the tool. Hope this helps. Thanks. Colin.

    ReplyDelete
  14. @Colin, thanks for the update!

    ReplyDelete
  15. Anonymous2:18 PM

    One more comment. The new version (2.0) of XsdObjectGen (located on www.codeplex.com/ivc in the IvcAcordAccelerator zip) supports generic lists, partial classes, the ability to generator only some of the elements (a subset of the schema), etc. Lot's of new features. Thanks. Colin Cole.

    ReplyDelete
  16. Anonymous10:07 AM

    How do you generate only a subset of the schema using XsdObjectGen? I can't find it documented anywhere?

    ReplyDelete
  17. Anonymous5:50 AM

    version 1.4.4.1 of XsdObjectGen.exe does include a undocumented parameter '/p' for generating partial classes.

    ReplyDelete

Post a Comment

Popular posts from this blog

Effectively Promoting your Blog (or WebSite)

WCF Service Debugging with the serviceDebug element.

ASP.NET: Loss of Session / Cookies with Frames