Service Model Attribute Defaults

Published 12 March 07 05:40 PM | andersnoras 

Yesterday I did a spike to enable injection of WCF service model declarations. This is the type of adventure that is both painful and fun at the same time. One of the pains was how the various service model attributes such as ServiceContractAttribute and OperationContractAttribute handle their defaults.

"Do provide sensible default values for all properties, ensuring that
the defaults do not result in a security hole or an extremely inefficient design."
Framework Design Guidelines by Krzysztof Cwalina and Brad Abrams

The properties of these attributes are not roundtripable in the sense that you cannot assign the existing property values to the properties. The following test fails because some of the property setters validate the assigned value and default values like null are not accepted by the setters.

[Test]
public void CanRoundtripProperties()
{
    ServiceContractAttribute attr=new ServiceContractAttribute(); 
    Assert.IsNull(attr.Name);
    Assert.IsNull(attr.Namespace);   
    Assert.IsNull(attr.ConfigurationName);
    Assert.IsNull(attr.CallbackContract);
    attr.Name = attr.Name;
    attr.Namespace = attr.Namespace;
    attr.ConfigurationName = attr.ConfigurationName;  
    attr.CallbackContract = attr.CallbackContract;
}

In the common usage scenarios this will not be a problem because the attribute is applied declaratively and the defaults will be handled by the Windows Communication Framework.
The pain manifests itself when you try to work with these in code. My particular problem was that I used Castle Dynamic Proxy 2 to build the service interfaces and implementation dynamically at runtime. The Dynamic Proxy builder replicates attributes declared on a proxied type on the proxy. The AbstractTypeEmitter.DefineCustomAttribute does the code generation work and this operation can also be used to declare a new attribute on a type. When Dynamic Proxy copies an attribute, it first does constructor injection and injects any property values not injected through the constructor.

ServiceContractAttribute attribute=new ServiceContractAttribute();
emitter.DefineCustomAttribute(attribute);

Because of the invalid defaults mentioned earlier, this code will cause an exception. This requires the service model attributes to be handled as special cases with custom replication logic.

This isn't an issue when you use these types as intended, but it is good to be aware of this if you attempt to do any "outside the box" work with WCF.

Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Enter the code you see below