When you start to work with TDD and other Agile practices the first thing you try to apply almost everywhere in your code is the Dependency Inversion pattern because you want to invert the logic of your dependencies to make your code more testable and maintainable.
In order to accomplish this result I am using Castle Windsor, while before 2013 I was working with Microsoft Unity. I am not going to jump into the conversation “Which Inversion of Control container is better?” because it really depends on what you need to do. For years I was more than satisfied with Unity but recently I started to create complex bootstrappers for my applications and I found Windsor more flexible, that’s it!
How does WCF create a service instance?
First of all, in order to apply dependency inversion inside WCF we need to understand how WCF works and how it creates new service instance. I found this article on MSDN very helpful during my researches: Extending WCF.
So, this is the final result I want to obtain:
When you create a new service in WCF, you can specify the factory that will be in charge of creating the service instance.
This is the code you should use to specify the factory:
Now, the factory should start a new instance of our service, or better, should use the ioc container to resolve an instance of that service.
Second step is to create a custom host that will add a new behaviour to our service, the behaviour will call the service locator (I know it’s an anti-pattern …) to inject the dependencies. In my case, Castle Windsor.
So, the instance provider is able to retrieve a registration for our service using the service locator:
That’s it. Of course my container needs to know what is my service registration, and with Windsor I have two options:
And of course you need to change the markup of your .svc file depending on how you want to resolve the service, with the interface or with the class type.
Now, let’s assume that my service needs an IUnitOfWork contract, how should we do that?
First of all we need to register both types in our container, and with Windsor one of the possible options is this one:
And my command service is constructed in this way:
Note for purist of CQRS: I know that a command service should get a command dispatcher injected but for this blog post I guess it would not make things clear enough, so a unit of work or an IRepository would make more sense.