In honor of the
contract-first service development philosophy, I'm going to be creating
XSD schemas as
contracts for some Web Services I'm writing. Taking a pragmatic approach, I'm
thinking of creating the necessary schemas and then using the
xsd.exe command line utility to create
Data Transfer Objects (DTOs) based on them. I really like xsd.exe for
creating typed-DataSets, and it is kinda cool that you can derive XSDs from .NET
classes with it (although I don't see that ever happening), but I'm kinda bumbed-out
that it creates public fields rather than properties. I know this isn't a
limitation in Visual Studio 2005 because they
changed generating fields to properties to allow databinding. Also, you really shouldn't be doing anything with DTOs other than using them to create your BL objects, etc - but the
problem of
the limited contract-first available toolset is an issue. I'm going to be
looking around for some nice tools for this kind of development. Drop me a line
if you have any suggestions. It would be nice, for example, to have a more
robust xsd.exe utility that could possibly enforce things like pattern
restrictions defined in an XSD. For example, I was playing around with an
example schema on
http://www.w3.org/TR/xmlschema-0/ that had an SKU type defined like this...
<xsd:simpleType
name="SKU">
<xsd:restriction
base="xsd:string">
<xsd:pattern
value="\d{3}-[A-Z]{2}"
/>
</xsd:restriction>
</xsd:simpleType>
<xsd:attribute
name="partNum"
type="SKU"
use="required"
/>
Once I run "xsd.exe /c" to create a class based on that schema, there's no
enforcement of that pattern, nor does the Web Service care during the SOAP call
(which isn't suprising). The generated class for
partNum
looks like this...
[System.Xml.Serialization.XmlAttributeAttribute()]
public
string partNum;
Maybe it isn't feasible to enforce this. Another example is if I create a Foo
element with a couple of Bar types and I set maxOccurs to 2...
<xs:element
name="Foo">
<xs:complexType>
<xs:sequence>
<xs:element
name="Bars"
type="Bar"
minOccurs="0"
maxOccurs="2"
/>
<xs:element
name="FooName"
type="xs:string"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
There's no problem creating 10 elements and breaking the maxOccurs schema
definition...
//Add more than 2 bars...
localhost.Foo f = new localhost.Foo();
f.Bars =
new localhost.Bar[10];
for(int
i = 0; i < 10; i++)
{
f.FooName = "F" + i;
f.Bars[i] = new localhost.Bar();
f.Bars[i].Name = "B" + i;
}
service.Test2(f);
The bottom line here is that it would be nice to at least have some great
tools for contract-first (or the "hybrid approach") to service development.