Common Service Host for Windows Communication Foundation

After having to write new instance providers, host factories and service behaviors for almost every new WCF project; I decided to write a simple reusable component for WCF and dependency injection and put it on codeplex so that I never had to write that again.

The idea is simple, when creating service hosts you more often then not want a centralized controlling factory that handles your dependency wiring and life time management of said dependencies. WCF requires you to add custom code to the initialization extension points.

Enter the Common Service Host. Based on the Common Service Locator interface and model it allows for a single library with classes for any DI-Framework to automatically wire up your service instances. From the codeplex documentation:

Example host configuration:

public class AppContainer : UnityContainerProvider
{
        public void EnsureConfiguration()
        {
            UnityContainer.RegisterType<IRepository, Repository>();
        }
} 

Example self-hosted usage:

using(var host = new CommonServiceHost<AppContainer>())
{
    host.Open();
}

Example usage for a .svc file:

<%@ ServiceHost Language="C#" 
      Service="Sogeti.Guidelines.Examples.Service1" 
      Factory="Sogeti.Guidelines.WCF.Hosting.CommonServiceHostFactory`1
	[[Sogeti.Guidelines.Examples.AppContainer,
 Sogeti.Guidelines.Examples.Service]], Sogeti.Guidelines.WCF.Hosting" %>

 

Included providers in the current release for Unity and spring.net

Get your copy here: http://commonservicehost.codeplex.com

Unity LifeTimeManager for WCF

I really love DI-frameworks. One reason is that it allows me to centralize life-time management of objects and services needed by others. Most frameworks have options to control the lifetime and allows objects to be created as Singletons, ThreadStatics, Transients (a new object everytime) etc.

I’m currently doing some work on a project where Unity is the preferred DI-framework and it’s hooked to resolve all service objects for us.

The challenge

WCF has three options for instances, PerCall, PerSession and Single (http://msdn.microsoft.com/en-us/library/system.servicemodel.instancecontextmode.aspx). IN essence this will have the following effect on dependencies injected:

PerCallAll dependencies will be  resolved once per message sent to the service.
PerSession – All dependencies will be resolved once per WCF service Session.
Single – All dependencies will be resolved exactly once (Singleton).

Now why is this challenge? It’s as expected that the constructor parameters is called once per instantiation, isn’t it?

The basis of the challenge is when you want to share instances of dependencies one or more levels down. Consider this code: ´

  1: public class CalculationService : Contract {
  2:   public CalculationService(IRepository<Rule> ruleRepository, 
  3:                             IRepository<Product> productRepository){..}
  4: }

This would work perfectly fine with the InstanceContextModes explained above, but what if we want to share instances of NHibernate Sessions or Entity Framework Contexts between repositories?

The default setting for most DI-Frameworks is to always resolve objects as “Transients”, which means once for each object that is dependent on them.

This is where LifeTime management comes into play by changing how the DI-Framework shares instances between dependant objects.

Unity has six “sharing-options” (from http://msdn.microsoft.com/en-us/library/ff660872(PandP.20).aspx):

TransientLifetimeManager: A new object per dependency
ContainerControlledLifetimeManager One object per unity container instance (including childrens)
HierarchicalLifetimeManager One object per unity child container
PerResolveLifetimeManager A new object per call to resolve, recursive dependencies will reuse objects.
PerThreadLifetimeManager One new object per thread
ExternallyControlledLifetimeManager Moves the control outside of Unity

As you can see we are missing our scenario. We’d like to share all dependencies of some objects across a single service instance, no matter what InstanceContextMode we choose.

The Solution

For Unity there is a good extension point that can help us. Combine that with WCF’s ability to add extensions to Instances and problem will be solved.

First we extend WCF instance context so it can hold objects created by Unity:

  1: public class WcfServiceInstanceExtension : IExtension<InstanceContext>
  2: {
  3:     public static WcfServiceInstanceExtension Current
  4:     {
  5:         get
  6:         {
  7:             if (OperationContext.Current == null)
  8:                 return null;
  9: 
 10:             var instanceContext = OperationContext.Current.InstanceContext;
 11:             return GetExtensionFrom(instanceContext);
 12:         }
 13:     }
 14: 
 15:     public static WcfServiceInstanceExtension GetExtensionFrom(
 16:                                               InstanceContext instanceContext)
 17:     {
 18:         lock (instanceContext)
 19:         {
 20:             var extension = instanceContext.Extensions
 21:                                            .Find<WcfServiceInstanceExtension>();
 22: 
 23:             if (extension == null
 24:             {
 25:                 extension = new WcfServiceInstanceExtension();
 26:                 extension.Items.Hook(instanceContext);
 27: 
 28:                 instanceContext.Extensions.Add(extension);
 29:             }
 30: 
 31:             return extension;
 32:         }
 33:     }
 34: 
 35:     public InstanceItems Items = new InstanceItems();
 36: 
 37:     public void Attach(InstanceContext owner)
 38:     { }
 39: 
 40:     public void Detach(InstanceContext owner)
 41:     { }
 42: }

InstanceContextExtension, which get’s applied on each WCF Service Instance

  1: public class InstanceItems
  2: {
  3:     public object Find(object key)
  4:     {
  5:         if (Items.ContainsKey(key))
  6:             return Items[key];
  7: 
  8:         return null;
  9:     }
 10: 
 11:     public void Set(object key, object value)
 12:     {
 13:         Items[key] = value;
 14:     }
 15: 
 16:     public void Remove(object key)
 17:     {
 18:         Items.Remove(key);
 19:     }
 20: 
 21:     private Dictionary<object, object> Items 
 22:                          = new Dictionary<object, object>();
 23: 
 24:     public void CleanUp(object sender, EventArgs e)
 25:     {
 26:         foreach (var item in Items.Select(item => item.Value))
 27:         {
 28:             if (item is IDisposable)
 29:                 ((IDisposable)item).Dispose();
 30:         }
 31:     }
 32: 
 33:     internal void Hook(InstanceContext instanceContext)
 34:     {
 35:         instanceContext.Closed += CleanUp;
 36:         instanceContext.Faulted += CleanUp;
 37:     }
 38: }

InstanceItems, used by the extension to hold objects created by unity

This gives us a nice place to put created objects, it will also call dispose on any objects when the instance is closing down.

Now we need to tell Unity to use our new shiny class, this is done by first extending LifeTimeManager:

  1: public class WcfServiceInstanceLifeTimeManager : LifetimeManager
  2: {
  3:     private readonly Guid key;
  4: 
  5:     public WcfServiceInstanceLifeTimeManager()
  6:     {
  7:         key = Guid.NewGuid();
  8:     }
  9: 
 10:     public override object GetValue()
 11:     {
 12:         return WcfServiceInstanceExtension.Current.Items.Find(key);
 13:     }
 14: 
 15:     public override void SetValue(object newValue)
 16:     {
 17:         WcfServiceInstanceExtension.Current.Items.Set(key, newValue);
 18:     }
 19: 
 20:     public override void RemoveValue()
 21:     {
 22:         WcfServiceInstanceExtension.Current.Items.Remove(key);
 23:     }
 24: }

The LifeTimeManager that uses our WCF Extension

All that’s left now is to tell Unity when to use this LifeTimeManager instead of the default. That is done when we register the type:

container.RegisterType<ISession>(new WcfServiceInstanceLifeTimeManager(), 
                                 new InjectionFactory(
                                     c => SessionFactory.CreateSession()));

In conclusion

So, DI-Frameworks are powerful to handle dependencies but sometimes they need a little nudge in the right direct. Custom LifeTimeManagement is one of those nudges you can do and both Unity and WCF helps you do that.

Architecture considerations: When do I benefit from services?

As a .NET developer it’s becoming increasingly tempting to create service layers for our application and utilize some of the strengths in Windows Communication Foundation in our solutions. With the power WCF brings to the table and all the messages about SOA in general, it’s easy get swept into it all and default to distribution.

In this post I will try to outline some scenarios where a service layer might be beneficial and alternatives that might suite that scenario better sometimes.

Other applications needs to integrate with you

If there is other applications that want to integrate with you, chances are that services might be your solution. Before you start writing your service layer you owe yourself to think about why the other application is integrating with you.

Pushing data to or from you

If other applications are solely interested in pushing data to or from you, a service might not be the best answer. There is other tools such as Sql Server Integration Services that is better suited for data import / export of this kind.

If all you want to do is share some piece of information, like your product catalog, it might even be as simple as exposing a XML-document. No need for a service layer. (all though WCF does a good job exposing XML-documents with the REST starter-kit).

You want to expose a business process

This is the block-buster feature of a service. Create a service and expose your business processes. Does this mean you will have to expose all of your business processes as services and have a service layer in your applications? Usually no.  Usually it’s enough to create an integration point, a anti-corruption layer or a small service exposing exactly what you want integrated. There is no real need for a full blown tier separation.

Wait a minute, is there no reasons for the service tier?

Of course there is. There is a couple of really good reasons. Most of them tied into the word “tier”. When do I need a separate “tier”? A couple of of reasons:

Lightweight UI’s like Silverlight or Flash

Advanced business logic is usually heavy weight. It involves a lot of code and usually it doesn’t belong on the client side. For lightweight UI’s, or Rich Internet Applications (RIA), this is very true. You want the full power of the CLR and the .NET framework for your applications and to get that you’ll need to separate the application into at least two tiers.

Wanting “middleware” in your application

Often there is the need for integration with other systems, orchestration of some sort or interesting conversation patterns like publish / subscriber. This is not the job for a client but for middleware. Or a “server”. In this case, separating the back-end into it’s own tier is a really good idea.

Summary

So use your service tier wisely, there isn’t one pattern and one usage of it and often it’s not the only solution or even the best.  The extra tier will bring extra complexity so make sure it will carry it’s own weight.

Is Windows Communication Foundation to complex?

Today at ALT.NET’s unconference we had a great discussion initialized by Alan Smith about the state of WCF and the complexity, if any, it imposes on developers. The thesis was that WCF was hard to learn for the “Average developer” and there was a lot of underlying details of communication that might be too visual. Alan showed an example of all the details generated by SvcUtil in it’s default settings. He compared with ASMX web services where “regular” asp.net developers could develop new services as simple as they implemented an event handler.

My view on this is kind of simple and ties into discussions I’ve had in the past about The holy abstraction level, the real question to ask is if I and my project is ready for distribution? Am I skilled enough to wield a tool for building services?

ASMX is a bit simpler, sure, if you don’t want real security. Or are looking for reliable sessions or any other more interesting service conversation pattern then request/response over HTTP.

The simple truth is that anything but request / response has a lot of underlying principles that are far from easy. These principles is what WCF aims to be an abstraction layer for. Not HTTP request / response. Sure, there is a lot of things that can be simpler. More things that tools can do for you to make you faster. Some of the simpler conversation patterns could be easier to implement.

But the problem will still be the same, building distributed applications that scale, perform are reliable and secure is not a walk in the park. It requires skill, planning and a lot of thought.

Distributed applications are hard for a reason and no tool will make architecting them easy, any tool that try will fool developers into dangerous traps.

So in short, it’s not WCF that’s too complex, WCF takes complex conversation patterns to the average developer and that makes WCF seem complex at a first glimpse.

If you want to master WCF development, your first step should be to master distributed application design and conversation patterns. When you do; WCF will be an excellent and simple enough tool for you.