Posts tagged Services

Five Things to Know About the WCF Runtime

Since working with WCF I have gleaned quite a bit about how the runtime works through reading various blogs and writing proofs-of-concept/experiments.  One thing that has become apparent to me is that many people working with WCF do not fully understand how it works because Visual Studio makes it very easy to create & consume WCF services.  In most cases there is no need to understand the “guts” of WCF, but you may reach a point where you want to extend WCF.  Here are five things that will help you know where to begin your quest for extension.

.Svc file are the activators that kick off the WCF runtime.  In IIS or WAS, .Svc files are what activates a service host which in turn creates a service host and calls your service.  The .Svc file specifies the full name of your class and an optional service host factory.  If you are self-hosting a service you are responsible for implementing the same functionality in code.

ServiceHosts control your service instances and dispatch calls to your service using ChannelDispatchers.  The ServiceHost is the central actor and you can control a lot of behavior by altering the service host or extending it.  If you want to use an Inversion of Control container with WCF the best place to stick it is on a custom ServiceHost.  The service host also maintains listeners that enable your service to receive calls over the wire at the specified endpoint (e.g., http://mydomain.com/services/myservice.svc). 

ServiceHostFactory creates a ServiceHost.  If you want to create a custom service host you’ll need a ServiceHostFactory to return an instance of your service host to the WCF runtime.

Everything can be done through configuration or code.  I used to be a huge configuration fan, but after dealing with WCF configuration in .NET 3.5 it can get hairy, especially when you have dozens of services.  Favor code where you can and save configuration for the stuff that could really change.  WCF in .NET 4 has far less configuration, especially in development (which is good because the last thing you want to fight is configuration problems during development of your service).

By default service instances are created per call.  This is typically OK and helps you avoid most threading problems.  Try to avoid creating expensive objects within your services constructor or any of its dependencies as this could delay your services response time.  You can change this using the InstanceContextMode on your service class. Tip: If you are using a container to resolve service instances then you need to remove the InstanceContextMode attribute and let the container manage instances.

(Bonus, a 6th thing to know!) WCF has many extension points, the biggest one being behaviors.  Behaviors allow you to control how the service executes at runtime.  This applies to anything from instancing to message inspection, and much more.  Here are a few posts to get you started:

WCF: InstanceContextMode.Single and ReleaseServiceInstanceOnTransactionComplete

WCF was designed with a lot of options for you to tweak so your services run the way you need them to.  This flexibility is probably my favorite feature of WCF because you have a lot of power to choose things like instancing mode, transactional support, and so on.  The drawback is "discovering" how these things work together.

I have a transactional queued service that needs to behave like a singleton.  This service holds onto a resource that must always be available and there should not be many instances of it running (it’s a TCP socket listener so I don’t want a new one for every message I process).  During testing I discovered that though I had the InstanceContextMode set to Single WCF was still creating a new instance for each message received.  After some research I decided to tweak a few knobs starting with ReleaseServiceInstanceOnTransactionComplete.

While that name is probably longer than what Mcconnell might suggest it sure does make it clear what behavior to expect.  The property is a boolean but I went ahead and set it specifically to false and voilà, problem solved.  My service now behaves as a singleton.  For good measure I also set the ConcurrencyMode to Multiple to ensure that my service can be accessed by multiple threads.  Because I’m doing a lot of asynchronous work it will perform better under these settings.

Technorati Tags: ,,,