Freigeben über


System Types in Metadata

It's bad practice to use system types when defining an operation contract. A system type is often a complex composition of primitive types that has no direct analog in other implementations. By using a system type, you bind your service to the particular implementation used by that type, which effectively ends any chance of having an easily interoperable service.

For example, a contract containing an IPAddress seems innocuous.

 [OperationContract]
string LookupHostName(IPAddress address);

However, that reference translates into a significantly sized chunk of metadata for defining the IPAddress type.

 <xs:schema xmlns:tns="https://schemas.datacontract.org/2004/07/System.Net" elementFormDefault="qualified" targetNamespace="https://schemas.datacontract.org/2004/07/System.Net" xmlns:xs="https://www.w3.org/2001/XMLSchema">
  <xs:import namespace="https://schemas.datacontract.org/2004/07/System.Net.Sockets" />
  <xs:import namespace="https://schemas.microsoft.com/2003/10/Serialization/Arrays" />
  <xs:complexType name="IPAddress">
    <xs:sequence>
      <xs:element name="m_Address" type="xs:long" />
      <xs:element xmlns:q1="https://schemas.datacontract.org/2004/07/System.Net.Sockets" name="m_Family" type="q1:AddressFamily" />
      <xs:element name="m_HashCode" type="xs:int" />
      <xs:element xmlns:q2="https://schemas.microsoft.com/2003/10/Serialization/Arrays" name="m_Numbers" nillable="true" type="q2:ArrayOfunsignedShort" />
      <xs:element name="m_ScopeId" type="xs:long" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="IPAddress" nillable="true" type="tns:IPAddress" />
</xs:schema>

Notice the inclusion of System.Net.Sockets.AddressFamily. This schema is only the tip of the iceberg. It continues on and becomes much, much worse.

Nevertheless, there are times when you can accept putting interoperability aside and have a reason to bind your service to a system type. The metadata still leaves you with the problem of generating a working proxy. Although some system types are recognized and filtered out, other types slip through and will lead to compilation errors due to conflicting type definitions.

The standard referencing mechanism of svcutil works with system types as well as your types. You just need to find and point svcutil at the appropriate dll so that it can compute the types to exclude. Since IPAddress is defined in system.dll, if you wanted to resolve a conflict, you could use /r:%windir%\microsoft.net\framework\v2.0.50727\system.dll as a svcutil option to prevent duplicate type generation.

Next time: Certificate Revocation Cache

Comments

  • Anonymous
    August 05, 2008
    The address filter mode that we looked at last time solved the problem of funneling all of the messages

  • Anonymous
    August 09, 2008
    An inaccurate heuristic would be to filter anything residing in a namespace beginning with System., MS. or Microsoft. prefix.