Tag Archives: Ninject

ASP .NET Web API Dependency Injection with Ninject

In this article, we’re going to set up dependency injection in a new ASP .NET Web API project, using Ninject as our IoC container.

For starters, do the following:

  1. Create a new Web API project.
  2. Install the Ninject.Web.WebApi NuGet package.
  3. Install the Ninject.Web.WebApi.WebHost NuGet package.

Since I need an injectable service to demonstrate this with, I’m also going to install my very own .NET Settings Framework via the Dandago.Settings NuGet package.

When you installed Ninject.Web.WebApi.WebHost, it added a NinjectWebCommon.cs class under the App_Start folder:

ninjectwebapi-ninjectwebcommon

Ignore the boilerplate crap and look for the RegisterServices() method. There, you can set up your dependencies. In my case, it looks like this (needs namespace Dandago.Settings):

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IConfigKeyReader>().To<AppSettingReader>();
            kernel.Bind<IConfigKeyProvider>().To<ConfigKeyProvider>();
        }     

Great! Now, let’s test it. Find ValuesController and at the following code at the beginning:

        private int x;

        public ValuesController(IConfigKeyProvider configKeyProvider)
        {
            this.x = configKeyProvider.Get<int>("x", 5);
        }

Run it, and we should hit the breakpoint when going to /api/values:

ninjectwebapi-breakpointhit

It’s working, and that’s all you need.

In case it wasn’t that smooth, however, here are a couple of things that might have gone wrong.

ninjectwebapi-parameterless-constructor

If you’re getting the above error complaining about not having a parameterless public constructor, then you probably forgot to install the Ninject.Web.WebApi.WebHost package.

ninjectwebapi-activationexception

If on the other hand you went ahead and installed Ninject.Web.WebApi.WebHost first, that brings in an older version of the Ninject.Web.WebApi package, causing the above ActivationException. The solution is to upgrade Ninject.Web.WebApi.

Dependency Injection in WCF Services with Ninject

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.

wcfdi-createproject

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:

wcfdi-parameterlessconstructorerror

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):

wcfdi-ninject.extensions.wcf

With that done, right click on Service1.svc and select “View Markup“:

wcfdi-viewmarkup

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:

wcfdi-global-application-class

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.

wcfdi-running-correctly

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.