Best practices in WCF: Service design and performance guidelines

Take advantage of the recommended practices in WCF to build services that are responsive and can scale seamlessly over time

WCF service design and performance guidelines

In this post I'll present a discussion on WCF service design and performance guidelines and the recommended best practices. In future posts in this series of articles on WCF best practices, I'll discuss other aspects like security, configuration, error handling, deployment, etc.

Design guidelines

You should separate service contracts from service implementation. You can also instantiate your WCF service using an IoC container to facilitate loose coupling. This approach would also allow you to inject configuration metadata to your service at runtime. You should decorate an interface using the ServiceContract attribute and refrain from specifying this attribute on a class, i.e., your service contracts should be interfaces and not classes.

You can manipulate the service headers to specify metadata like, culture, session data, etc. You should leverage the ServiceContract, DataContract, ServiceBehavior attributes to decorate your types and facilitate versioning of your service methods. You can use data transfer objects to exchange data back and forth between the service and the domain objects -- you can take advantage of the adapter design pattern. It is also advisable to decouple the WCF configuration metadata from the web.config file to facilitate editing the WCF bindings, behaviors, etc. for each environment your service is supposed to work on.

Designing your service contract to accommodate future changes

I admit that change is inevitable, but with a proper plan and guidelines in place, incorporating and accommodating changes in your service layer is just seamless. You should use the Name, Namespace parameters on all contracts and also use the Order parameter on all the data members. If you would like to remove a service operation or update a service operation, refrain from changing the existing one -- rather, create new ones.

Another preferred approach to manage changes to your service operations over time is to implement a message oriented design in each of your services. This implies that each of your WCF service methods would receive a message and also send out a message. The benefit of this approach is that when you need to update your service methods over time, you can still leverage this design -- the future versions of your service implementation would not need a change in the service contract. In essence, you are not constrained to changing your service contract when a change request comes in as far as the design of your service contract is concerned. Any additional parameters you might need in your service methods may just be as simple as adding an optional parameter to the input message. Also, if your response message needs additional parameters, you can just add a few additional properties to the response message. This message driven design of your service contract would also facilitate backwards compatibility.

It is a good practice to use the async programming pattern when you are calling WCF services to ensure that your user interface can work in a non-blocking mode. It is a recommended practice to use RESTful services when you would like to build light-weight and scalable WCF services that would leverage the HTTP protocol. On the other hand if you would like to build a B2B application and you would like to take advantage of interoperability and also leverage the WCF's capability of working on multiple protocols, SOAP is a good choice.

Performance guidelines

If your WCF service is hosted on IIS you can turn on IIS compression for static and dynamic content to improve performance.  You can use the Windows Performance Monitor to analyse the performance bottlenecks. You can enable WCF performance counters by specifying the following in your web.config file.


 <diagnostics performanceCounters="All" />

Take advantage of NetTCP binding to boost the throughput of your WCF services. Use light-weight data exchange formats, i.e., JSON in your WCF service to minimize the network traffic that your WCF service would otherwise need to consume if SOAP were used as a data exchange format. You should always use DataContract Serializer in lieu of XMLSerializer for better performance. You can also explore the possibilities of using binary serialization formats like MessagePack or Google's Protocol Buffers to minimize the traffic even further.

You can also compress the data transferred over the wire to cut down on the network traffic between the service provider and the service consumers. Since there is no built in way to cache service responses in WCF, you can write custom code to cache service responses. You should set WCF service throttling and service configuration appropriately to improve service performance. I would discuss more on WCF service performance in the subsequent posts here. For now, you can take a look at this post for more information on the configuration thresholds.