Dependency Injection in WCF Service
In this post I will show you how to use dependency injection in a typical WCF Service and the architecture of the solution is a standard layered approach i.e. Service calls the business logic layer and business logic layer calls the data access layer etc.
In order to use Dependency Injection in WCF we are going to use the WcfFacility provided by Castle Windsor. This is another one of those good extension points in Castle Windsor which implements the IFacility interface and this is the class that does all the underlining pluming of WCF Service host.
In order to get started with WCF facility lets download it from the castle project from github website which is at http://github.com/castleproject/Castle.Facilities.Wcf.
Build the project which will build the binary, and we will need all the three binaries i.e.
- Castle.Core.dll
- Castle.Windsor.dll
- Castle.Facilities.WcfIntegration.dll
I had a bit of gotchas here as my project had reference to the previous version of Castle.Core and Castle.Windsor i.e. 2.5.0 and the newly build Castle.Facilities.WcfIntegration was of version 2.5.1 so make sure you copy all the three assemblies to your project.
Now my favourite part that is File > New > WCF Service application
Lets get down to writing some code. First we will create the data access layer using a repository pattern, this is just an illustration of an end-to-end dependency injection.
ICustomerRepository.cs
{
Customer GetById(int Id);
}
Customer.cs
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
CustomerRepository.cs
{
public Customer GetById(int Id)
{
return new Customer {
Id = 5,
FirstName = "Joe",
LastName = "Blogg",
Age = 45
};
}
}
Moving one layer up lets build the business logic layer in which we will also use constructor injection to inject the dependency, also for easy illustration I am going to create the business logic layer and service layer as simple pass through and you will see that they don’t do much but in real life project it would be much more sophisticated and complex too.
ICustomerBl.cs
{
Customer GetById(int Id);
}
CustomerBl.cs
{
private readonly ICustomerRepository repository;
public CustomerBl(ICustomerRepository repository)
{
this.repository = repository;
}
public Customer GetById(int Id)
{
return repository.GetById(Id);
}
}
We are almost there, lets finish the services layer too.
{
[OperationContract]
Customer GetById(int Id);
}
CustomerService.cs
{
private readonly ICustomerBl customerBl;
public CustomerService(ICustomerBl customerBl)
{
this.customerBl = customerBl;
}
public Customer GetById(int Id)
{
return customerBl.GetById(Id);
}
}
And this is how my end project structure looks like.
Now with all the coding done lets see how we will wire up rest of the stuff. First we need to change the declaration in service file and in order to do that, just right-click on the CustomerService.svc and open with XML (Text) Editor and add the following code.
CustomerService.svc
Service="WindsorWcfIntegration.CustomerService"
Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration"
CodeBehind="CustomerService.svc.cs" %>
With the above declaration we are saying that when ever the customer service is requested the DefaultServiceHostFactory will take care of how the service is created and instantiated. Let’s wire this up with the WcfFacility and since it has to happen at some startup process so we will do that in Global.asax file of the WCF Service project.
Global.asax.cs
{
public WindsorContainer Container { get; protected set; }
protected void Application_Start(object sender, EventArgs e)
{
Container = new WindsorContainer();
Container.AddFacility<WcfFacility>();
Container.Register(
Component.For<ICustomerRepository>().ImplementedBy<CustomerRepository>(),
Component.For<ICustomerBl>().ImplementedBy<CustomerBl>(),
Component.For<ICustomerService>().ImplementedBy<CustomerService>()
);
}
}
As you can see in the above code we are instantiating a new instance of WindsorContainer and adding the WcfFacility and then we go ahead & register all the interfaces and its concrete implementation and at the end we register the service contract ( interface) and the implementing service class.
Now let’s do a quick test by running the wcf test client and as you can see the service comes out without any errors so it’s all good.
And when we invoke the GetById method we get our desired result.
Hope this serve as a quick start tutorial into DI and you will be able to use Dependency Injection in your WCF project.
thanks
Greetings, this is a genuinely absorbing web blog and I have cherished studying many of the content and posts contained on the web site, keep up the outstanding work and desire to read a good deal more stimulating articles in the future.
Thank you so much for your encouraging words. I will try to keep up with it and will keep on writing my interesting experiences while coding and working on my projects.
LOL – you should probably translate potenzmittel’s site… I don’t think he’s that genuine! P.s. Wellington is the greatest capital in the world – not Canberra!
Hi Charles,
Thanks for that advice yes i translated it in google and found out what you mean, can’t help with the web now a days. Yes I agree with what you said about Wellington and if you read about me I said “One of the most beautiful” and not the “only beautiful capital” ;-). But I know what you mean I have been to north Island and I was totally mesmerize by it’s beauty. I wish to visit it someday soon. 🙂
my God, i thought you were going to chip in with some decisive insght at the end there, not leave it
with ‘we leave it to you to decide’.
I really don’t understand what do you mean by your comment. If you need some more insight into it then email me your query and I will try my best to solve the problem.
I’m confused as to what the WcfFacility provided by Castle Windsor actually does. It’s function is not obvious and it seems as though is not necessary for this DI to work. Care to explain what the WcfFacility actually does?
Hi Prashant,
I tried the above sample and i am getting the below error when i run the Web Client, am I missing someting in the process ?
Type Repository.ICustomerRepository is abstract.
As such, it is not possible to instansiate it as implementation of service ‘Repository.ICustomerRepository’. Did you forget to proxy it?
Thanks
Also would like to know advantage of the above DI as service tightly bound to the ICustomerBl , please clarify
Thanks
Hi Prashant,
Not to worry about the below, Its working now. Would like to know the advantage advantage of the above DI as service tightly bound to the ICustomerBl?
Hi,
In my opinion the service is not tightly bound to ICustomerBl, as the service is bound to the interface and when ever a one class depends on another class through interface then it is automatically loosely coupled. Think it this way as the service is looking for any class which implements the interface rather than a hard coded class itself and in the container I am defining which class implements the interface this is the core principle of Dependency Injection.
If it still not clear than have a look at how WCF itself works, all the operation contract which we need to expose to the outside world are defined as and interface and then you have the actual service class which implements the interface(service contract).
how do you swap between your dummy class to your let’s say repository calling db or another web service?
DO you place attributes and setup config file?
Hi wcf200,
The pattern i follow is that for each project I create a BootStrapper class which has wiring up of DI.So for instance in my example I have put the container configuration code in the Application_Start method of the global.asax.cs file, Ideally it should be in a different class and there you can swap your component.Config file is also a nice way to change things on the fly.
Regards,
Prashant Brall
Hi there thanks for the post this is exactly what i was looking for and nicely explained 🙂
I really love your blog.. Pleasant colors & theme.
Did you develop this website yourself? Please reply back
as I’m trying to create my own personal website and would like to find out where you got this
from or just what the theme is named. Cheers!
Thanks for the compliment 🙂 the theme is INova .
I have been looking on this line for a bit more than three hrs this day and found your blog. Thanks it really helped me.
whoah this blog is magnificent i really like studying your posts.Keep up the great work!