Posterous theme by Cory Watilo

Filed under: WCF

Integrating WCF with your favorite IoC

A while back I was working on a project where I had to implement a Windows Communication Service for authenticating users. Internally the service was going to use a user repository to validate the provided credentials. I wanted to design the service in such a way that it didn't take a hard dependency on a specific user repository implementation, instead I wanted to make use of the Dependency Inversion Principle to decouple the service's dependency on the user repository.


The following code snippet is a scaffold for the authentication service.


[ServiceContract] public interface IAuthenticationService {     [OperationContract]     bool Authenticate(string username, string password); }public class AuthenticationService : IAuthenticationService {     /// <summary>     /// Initializes a new instance of the <see cref=”AuthenticationService” />     /// class, using the specified <see cref=”IUserRepository” /> instance.     /// </summary>     public AuthenticationService(IUserRepository repository)     {     }    public bool Authenticate(string username, string password)     {        // Validate the input and call the user repository to perform the        // authentication.     } }

The thing to pay attention to in the code above is the introduction of the non-default constructor. This constructor accepts an instance of a class which implements the IUserRepository interface, making the user repository a loose dependency of the service.


Now, if you think about it for a moment you realize that when you invoke a service, an instance of the service is magically created for you. There is no need to explicitly create the instance in order to be able to consume the request. However, in order to be able to decouple the dependency from the service and instead pass it into the service, you need to gain control over the creation of the service instance.


Thankfully the people on the Windows Communication Framework team decided not to keep the creation of the service instance to themselves, but instead make use of the Factory Method pattern. This provides the necessary extensibility point to take control over how the service instance is created.

The factory

You create a custom service factory by deriving from the ServiceHostFactoryBase class and provide the necessary implementation. This can be a bit tedious so fortunately most of the popular inversion of control containers already ship with custom factory implementations, which use the container to resolve dependencies.


I will be using Autofac in my sample, since it’s the inversion of control container of my choice. However if you are looking at doing this using a different container, then you might want to check out the solutions for Castle Windsor, StructureMap, Spring.NET, Unity or Ninject.


The first thing you will need to do is tell the Windows Communication Framework what factory you wish to use when it creates an instance of the service. You do this by editing the .svc file and add the Factory attribute.


When using Autofac you would do the following


<%@     Service="TheCodeJunkie.Wcf.AuthenticationService, TheCodeJunkie.Wcf"     CodeBehind="AuthenticationService.svc.cs"     Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory, Autofac.Integration.Wcf" %>

Make sure you have a reference to the Autofac.Integration.Wcf assembly or it is going to fail horribly when you try to call your service, because it won't be able to resolve the type of the factory.


Next you have to make sure that the type specified in the Service attribute is the Assembly Qualified Name of the type. By default the assembly part is not included in this attribute and without it the Autofac factory will be unable to locate the type of the service. Note that if you are using a different IoC or factory implementation, this might not be a required step.


Depending on what type of service you are building, you are going to want to use different Autofac factories to give you the desired functionality. If you are building SOAP services you should use the AutofacServiceHostFactory, but if you are building a REST service you should use the AutofacWebServiceHostFactory.

Configuring the service host

Once the service has been prepared, the container needs to be setup and registered with the factory so that it can pull the service instances out of it. The container is setup just like for any other dependency, but you also tell the factory which container it should be use to resolve the dependencies a service might have.


var builder =     new ContainerBuilder(); builder     .Register<FakeUserRepository>()     .As<IUserRepository>()     .SingletonScoped(); builder     .Register<AuthenticationService>()     .As<IAuthenticationService>()     .FactoryScoped(); AutofacWebServiceHostFactory.Container = builder.Build();

The Autofac factories have the common Container property, which is a static property. It only has to be set once even though you are hosting many different types of services. This also means that the SOAP and REST factory share the same container.

Conclusion

By following the Dependency Inversion Principle you can create services with loosely coupled dependencies, with only a few lines of code. This is possibly thanks to the fact that Microsoft decided to give you the option to control how a service instance is manufactured. It is also because of the rich support for WCF integration by the popular Inversion of Control containers.


Loose coupling enables you to make modifications to the behavior and capabilities of your application without having to rewrite it (see Open / Closed Principle). It also promotes writing maintainable and reusable code, as well enabling convenient unit testing.


Media_httpdotnetshout_umjrf
Media_httpwwwdotnetki_efbqu