Implementing dependency injection in a WCF service can be a little tricky since you don’t directly control the lifetime of the class that implements the interface. However, it is a simple matter to get it working with Ninject. This article by Aaron Stannard and this article by Tony Sneed were pretty useful to find the right direction; however they are a little out of date and the APIs have changed a little.
Part 1: Setting up a test scenario
Create a new WCF Service Application.
Create a new interface called IRepository:
public interface IRepository { }
Create a new class called Repository which implements the IRepository interface:
public class Repository : IRepository { }
In your Service1 class, add a constructor that depends on IRepository:
public class Service1 : IService1 { private IRepository repository; public Service1(IRepository repository) { this.repository = repository; } public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } }
Click on Service1.svc in Solution Explorer, and then press F5 to debug the application. Making sure that Service1.svc is focused, causes the WCF Test Client to be launched when you press F5.
Notice the error you get because of the constructor we just added:
Part 2: Setting up Ninject
Stop debugging. Right-click on your solution in Solution Explorer, and select “Manage NuGet Packages for Solution…“. Search Online for “ninject wcf“, and install Ninject.Extensions.Wcf (note that this also installs other related packages that you need):
With that done, right click on Service1.svc and select “View Markup“:
Configure the service to use the Ninject ServiceHost Factory by adding the line highlighted below:
<%@ ServiceHost Language="C#" Debug="true" Service="WcfDependencyInjectionNinject.Service1" CodeBehind="Service1.svc.cs" Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>
Next, add a new Global Application Class, either via the context menu shown below, or via Add -> New Item… under Web templates, and name it Global.asax:
The Global class you just created must inherit from NinjectHttpApplication, and needs to have a new CreateKernel() method to create the IoC container and configure any types (in this case our IRepository):
// ... using Ninject; using Ninject.Web.Common; namespace WcfDependencyInjectionNinject { public class Global : NinjectHttpApplication { protected override IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<IRepository>().To<Repository>().InSingletonScope(); return kernel; } // ...
Part 3: Testing
That’s all you need! Once again, select Service1.svc in Solution Explorer, and hit F5 to run the WCF Test Client.
As you can see, the WCF Test Client now connects to the service without any problems. You can put a breakpoint to see how a Repository instance is really being passed into the service’s constructor, and you can invoke service methods via the WCF Test Client.