Contract-First Development and Diagnosable Mental Disorders
Data sent from Windows Communication Foundation clients to Windows Communication Foundation Services is serialized to XML within the client, and de-serialized from XML within the service. There are two XML serializers that the Windows Communication Foundation can use to accomplish that.
One of those is a new XML serializer provided with the Windows Communication Foundation. It is the XmlFormatter class in the System.Runtime.Serialization namespace within the System.Runtime.Serialization assembly. That assembly is the one of the constituent assemblies of the Windows Communication Foundation. The XmlFormatter class is the XML serializer that the Windows Communication Foundation uses by default.
While the XmlFormatter is the default XML serializer of the Windows Communication Foundation, the Windows Communication Foundation can also be configured to do XML serialization using the System.Xml.Serialization.XmlSerializer class that has always been included in the System.Xml assembly of the .NET Framework Class Library. To exercise that option, add the XmlSerializerFormat attribute to the definition of a Windows Communication Foundation contract, like so:
namespace DerivativesCalculator
{
[ServiceContract]
[XmlSerializerFormat]
public interface IDerivativesCalculator
{
[OperationContract]
decimal CalculateDerivative(
string[] symbols,
decimal[] parameters,
string[] functions);
void DoNothing();
}
}
The option of using the XmlSerializer class for XML serialization can also be selected just for individual operations:
namespace DerivativesCalculator
{
[ServiceContract]
public interface IDerivativesCalculator
{
[OperationContract]
[XmlSerializerFormat]
decimal CalculateDerivative(
string[] symbols,
decimal[] parameters,
string[] functions);
void DoNothing();
}
}
The XmlSerializer provides very precise control over how data is to be represented in XML. Its facilities are well-documented in the book .NET Web Services: Architecture and Implementation, by Keith Ballinger (2003).
The XmlFormatter, on the other hand, provides very little control over how data is to be represented in XML. It only allows one to specify the namespaces and names used to refer to data items in the XML, and the order in which the data items are to appear in the XML, as in this case:
[DataContract(Namespace=”Derivatives”,Name=”Calculation”)]
public class DerivativesCalculation
{
[DataMember(Namespace=”Derivatives”,Name=”Symbols”,Order=0)]
private string[] symbols;
[DataMember(Namespace=”Derivatives”,Name=”Parameters”,Order=1)]
private decimal[] parameters; [...]
}
By not permitting any control over how data is to be represented in XML, the serialization process becomes highly predictable for the XmlFormatter and, thereby, more amenable to optimization. So a practical benefit of the XmlFormatter’s design is better performance, approximately 10% better performance.
Now, one might wonder whether the gain in performance is worth the loss of control over how data is represented in XML. That is most certainly the case, and understanding why serves to highlight the brilliance of the design of the Windows Communication Foundation.
A practice that is most characteristic of service-oriented programming is commonly-referred to as contract-first development. Contract-first development is to begin the construction of software by specifying platform-independent representations for the data structures to be exchanged across the external interfaces, and platform-independent protocols for those exchanges.
Contract-first development is a sound practice. It helps one to avoid such unfortunate mistakes as building software that is meant to be interoperable across platforms, but which emits data in formats for which there are only representations on a particular platform, such as the .NET DataSet format.
However, the sound practice of contract-first development has become confused with one particular way of doing contract-first development, by virtue of which people become excessively concerned with XML formats. That one particular way of doing contract-first development is to use an XML editor to compose specifications of data formats in the XML Schema language, taking care to ensure that all complex data types are ultimately defined in terms of XML Schema Datatypes. Now, as a software developer, one's sole interest in contract-first development should be in defining the inputs and outputs of one’s software, and in ensuring that, if necessary, those inputs and outputs can be represented in a platform-independent format. Yet, practitioners of contract-first development, working in the XML Schema language in an XML editor, tend to become distracted from those core concerns and start to worry about exactly how the data is to be represented in XML. Consequently, they begin to debate, amongst other things, the virtues of various ways of encoding XML, and become highly suspicious of anything that might inhibit them from seeing and fiddling with XML. The XML becomes a fetish, falsely imbued with the true virtues of contract-first development, and, as Sigmund Freud wrote, “[s]uch substitutes are with some justice likened to the fetishes in which savages believe that their gods are embodied” (1977, 66).
With the XmlFormatter, the Windows Communication Foundation not only restores the focus of software developers to what should be important to them, namely, the specification of inputs and outputs, but also relocates control over the representation of data to where it properly belongs, which is outside of the code, at the system administrator’s disposal. Specifically, given the class,
public class DerivativesCalculation
{
public string[] Symbols;
public decimal[] Parameters;
public string[] Functions;
public DataTime Date
}
all one should care about as a software developer is to be able to say that the class is a data structure that may be an input or an output, and that particular constituents of that structure may be included when it is input or output. The DataContract and DataMember attributes provided for using the XmlFormatter to serialize data allow one to do just that, as in,
[DataContract]
public class DerivativesCalculation
{
[DataMember]
public string[] Symbols;
[DataMember]
public decimal[] Parameters;
[DataMember]
public string[] Functions;
public DataTime Date
}
It is by configuring the encoding protocol in the binding of an endpoint that one can control exactly how data structures are represented in transmissions.
Now there are two scenarios to consider. In the first scenario, the organization that has adopted the Windows Communication Foundation is building a service. In the other scenario, the organization that has adopted the Windows Communication Foundation is building a client.
In the first of these scenarios, the Windows Communication Foundation developers define the data structures to be exchanged with their services using the DataContract and DataMember attributes. Then they generate representations of those structures in the XML Schema language using the Service Metadata Tool, introduced in the previous chapter. They provide those XML Schema language representations to developers wishing to use their services. The designers of the Windows Communication Foundation have expended considerable effort to ensure that the structure of the XML into which the XmlFormatter serializes data should be readily consumable by the tools various vendors provide to assist in de-serializing data that is in XML. Thus, anyone wishing to use the services provided by the Windows Communication Foundation developers in this scenario should be able to do so, despite the Windows Communication Foundation developers never having necessarily looked at, or manipulated, any XML in the process of providing the services.
In the second scenario, the Windows Communication Foundation developers use the Service Metadata Tool to generate code for using a software service that may or may not have been developed using the Windows Communication Foundation. If the XML representations of the inputs and outputs of that service deviate from the way in which the XmlFormatter represents data in XML, then the code generated by the Service Metadata Tool will include the switch for using the XmlSerializer instead of the XmlFormatter for serializing data to XML. That code should allow the Windows Communication Foundation developers to use the service, and once again, they will not have had to look at, or manipulate any XML in order to do so.
Should the fetish for XML prove too overwhelming, and one is compelled to look at the XML Schema language that defines how a class will be represented within XML, then the Windows Communication Foundation does make provision for that. Executing the Service Metadata Tool in this way,
svcutil /datacontractonly SomeAssembly.dll
where SomeAssembly.dll, is the name of some assembly in which a data contract is defined for a class, will yield the XML Schema language specifying the format of the XML into which instances of the class will be serialized.
The question being considered is whether the gain in performance yielded by the XmlFormatter is adequate compensation for it providing no control over how data is represented in XML. The answer that should be apparent from the foregoing is that control over how data is represented in XML is generally of no use to software developers, so, yes, any gain in performance in exchange for that control is certainly welcome. Moreover, anecdotal evidence suggests that serialization and de-serlialization are the most common and severe bottlenecks in services, so gains in performance at those points are likely to improve the overall performance of a service.
References
Ballinger, Keith. 2003. .NET Web Services: Architecture and Implementation. Reading, MA: Addison-Wesley.
Freud, Sigmund. 1977. Three Essays on Sexuality. In On Sexuality: Three Essays on Sexuality and Other Works, ed. Angela Richards. The Pelican Freud Library, ed. James Strachey, no. 7. London, UK: Penguin.
Comments
Anonymous
February 10, 2006
I don't know what CTP you are using, but as far as I can see you don't have a Namespace property available on the DataMemberAttribute.
The reason I read your post was because I found that you were setting a namespace on your DataMembers and that's just what I want.
Do you know if this is possible? and if there wasn't a typo in your sample code, are you using a newer release than the January CTP? Please let me know, johan-spam at andersson.net. Thanks!Anonymous
March 01, 2006
I was trying to get a pulse on Contract-driven Development and what the industry was saying, so I compiled...Anonymous
March 14, 2006
Relevant Quote
Link
The trouble is this promotes a very code-first approach. This really...Anonymous
January 25, 2008
PingBack from http://websitescripts.247blogging.info/ali-pashas-weblog/Anonymous
June 09, 2009
PingBack from http://weakbladder.info/story.php?id=5695