Dependency Injection in WCF using Castle Windsor

Background

Dependency Injection (DI) is a design pattern in Object Oriented Programming where the dependencies of a class are injected at runtime. These dependencies are mostly injected through a constructor (Constructor DI) or a property (Property DI). One of the main advantage of DI is it simplifies unit testing by allowing to inject mock dependencies in the place of real classes. In some cases we should have a default constructor in classes like in ASP.NET MVC controllers, WCF services etc. In WCF the service classes should have a default constructor else the framework will throw a runtime exception. To solve this problem developer ends up writing two constructors one is default and the other one is parameterized. The default constructor is used by the framework and the parameterized one is used by developers at the time of unit testing.

public class BlogService
{
	private readonly ILogger _logger;

	public BlogService()
	{
		_logger = new TextLogger();
	}

	public BlogService(ILogger logger)
	{
		_logger = logger;
	}
}

Although having two constructors suffice the job but we are violating the principles of dependency injection by instantiating the concrete classes in the default constructor. In the above example the BlogService class is tightly coupled with TextLogger by instantiating it in the default constructor and it's not a good practice. WCF is a highly extensible framework and fortunately it provides extension points even to customize the service instantiation. It looks like some of the DI containers simplifies our job of customizing service instantiation by providing their own custom service host factories.

In this article we are going to see about the WCF extension point IInstanceProvider that allows us to customize the service instantiation and how the DI container Castle Windsor simplifies the task of creating services without default constructor through its new integration facilities.

IInstanceProvider

In WCF service side the dispatchers are the components that pull the incoming messages and convert them into method invocations, these dispatchers have many extension points that allows us to modify their usual processing. There are two types of dispatchers: channel and endpoint. Each channel dispatcher contains a collection of endpoint dispatchers and each endpoint dispatcher contains a dispatch-runtime and this runtime has an extension point that allows us to customize service instantiation. More technically it is the DispatchRuntime class of the endpoint dispatchers that comes with a property named InstanceProvider which is of type IInstanceProvider through which we can place our custom implementation to instantiate services.

public sealed class DispatchRuntime
{	
	public IInstanceProvider InstanceProvider { get; set; }

	//other members
}

The IInstaceProvider is the component that creates and returns service instances to the host and it contains three methods shown below. The GetInstance methods return a new service instance while the ReleaseInstance method does some cleanup on disposing the instance.

public interface IInstanceProvider
{
	object GetInstance(InstanceContext contect);
	object GetInstance(InstanceContext context, Message message);
	void ReleaseInstance();
}

So the strategy is we have to create a custom implementation of this IInstanceProvider and set it to the DispatchRuntime through a service behavior. The service behavior is finally added to the service pipeline either through behavior element or a custom service host and factory. In most of the implementations out there the service behavior is added to the service through a custom service host and service host factory. There is a nice article available in MSDN that explains step-by-step from creating the custom instance provider to creating the service host factory.

It looks like customizing service instantiation is not that simple, we will end up creating many custom classes on the way when achieving this like custom instance provider, custom service behavior, custom service host and custom host factory. Some of the DI containers already come with a built-in custom service host factory that simplifies our job and Castle Windsor is one in that.

WCF Facility by Castle Windsor

The Castle Windsor is a powerful DI container created by Ayende Rahien which is extensively used by many developers for a long time to achieve dependency injection and in the latest version 3.0 it officially comes with a bunch of WCF integration facilities and one of the facility allows us to create service instances without default constructor through the Windsor's custom service host factory.

Let see how we can do that through a simple example.

[ServiceContract]
public interface IBlogService
{
	[OperationContract]
	Post GetPost(int postId);

	[OperationContract]
	int AddPost(Post post);

	[OperationContract]
	void EditPost(Post post);

	[OperationContract]
	void DeletePost(Post post);
} 
public class BlogService : IBlogService
{
	private readonly ILogger _logger;
	Private readonly IRepository _repository;

	public BlogService(ILogger logger, IRepository repository)
	{
		_logger = logger;
		_repository = repository;
	}
	
	// IBlogService methods
}

The IBlogService is a service contract that is implemented in the class BlogService and this class has a dependency with ILogger which is injected through the constructor. As you notice the BlogService class has no any default constructor but only a parameterized constructor. Let assume that the service is hosted in IIS and uses a HTTP protocol, so in this case we have to create the container and register the types in the Application_Start event of the Global.asax.cs.

Create the container

IWindsorContainer _container;
_container = new WindsorContainer();

Register the service and dependencies

_container.AddFacility<WcfFacility>()
	.Register
	(
		 Component.For<ILogger>().ImplementedBy<TextLogger>(),
		 Component.For<IRepository>().ImplementedBy<Repository>(),
		 Component.For<IBlogService>()
				  .ImplementedBy<BlogService>()
				  .Named("BlogService")
	);

WcfFacility is the new facility class that ships with the assembly Castle.Facilities.WcfInegration. The extension method Register first registers the implementations of the dependencies ILogger and IRepository and then the IBlogService. One important thing is we can specify a custom name for the service using the extension method Named and this value should be specified in the Service property of the Windsor's service host factory (svc file).

Here is the complete Global.asax.cs and svc file

public class Global : System.Web.HttpApplication
{
	IWindsorContainer _container;

	protected void Application_Start(object sender, EventArgs e)
	{
		_container = new WindsorContainer();

		_container.AddFacility<WcfFacility>()
			.Register
			(
				 Component.For<ILogger>().ImplementedBy<TextLogger>(),
				 Component.For<IRepository>().ImplementedBy<Repository>(),
				 Component.For<IBlogService>()
						  .ImplementedBy<BlogService>()
						  .Named("BlogService")
			);
	}

	protected void Application_End(object sender, EventArgs e)
	{
	  if (_container != null)
		_container.Dispose();
	}
}
<%@ ServiceHost Service="BlogService" 
Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" %>

In the service host declaration we have set the factory as the Windsor's DefaultServiceHostFactory which internally has a custom inplementation of IInstanceProvider. When the service host receives the request the container creates an instance of BlogService injecting it's dependencies through the parameterized constructor and returns it to the service host.

Now we have a service class that has only parameterized constructor in which is dependencies are injected from outside their by making the service extremely customizable and effective in unit testing.

Download Sample

blog comments powered by Disqus