9

Can anybody point me in the right direction to get Ninject working with WCF Web API Preview 5? I have it successfully up and running in my ASP.NET MVC 3 project and also in another internal WCF Service using the Ninject.Extensions.Wcf library. However I cannot get it to work when creating a new MVC 3 project and getting the WebApi.All library from NuGet.

I have looked at this stackoverflow post Setting up Ninject with the new WCF Web API but cannot get it working which I believe could be to do with some of the changes in the latest release.

I am also unsure which Ninject Libraries to reference beyond the main one. Do I use the Ninject.MVC3 , Ninject.Extensions.Wcf.

Any help on this would be much appreciated.

****UPDATE**

Code I am using which is from the answer in the question mentioned above. I have this in its own class file.

   public class NinjectResourceFactory : IResourceFactory
    {
        private readonly IKernel _kernel;

        public NinjectResourceFactory(IKernel kernel)
        {
            _kernel = kernel;
        }

        public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
        {
            return _kernel.Get(serviceType);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object service)
        {
            // no op
        }
    }

This I have in my global.asax:

var configuration = HttpConfiguration.Create().SetResourceFactory(new NinjectResourceFactory());
RouteTable.Routes.MapServiceRoute<myResource>("resource", configuration);

The issue I am having is that the IResourceFactory interface is not recognised and that the HttpConfiguration.Create() no longer exists so I need to set the SetResourceFactory some other way which I have tried to do using the HttpConfiguration().CreateInstance method but no joy.

Community
  • 1
  • 1
Cragly
  • 3,554
  • 9
  • 45
  • 59

3 Answers3

9

Following is my code with Ninject and WebApi,it works. Create a class inherites from WebApiConfiguration

public class NinjectWebApiConfiguration : WebApiConfiguration {
    private IKernel kernel = new StandardKernel();

    public NinjectWebApiConfiguration() {
        AddBindings();
        CreateInstance = (serviceType, context, request) => kernel.Get(serviceType);
    }

    private void AddBindings() {
        kernel.Bind<IProductRepository>().To<MockProductRepository>();
    }

}

and use the NinjectWebApiConfiguration in RegisterRoutes

public static void RegisterRoutes(RouteCollection routes) {

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    var config = new NinjectWebApiConfiguration() { 
        EnableTestClient = true
    };

    routes.MapServiceRoute<ContactsApi>("api/contacts", config);
}
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
zanewill
  • 108
  • 7
  • I used this approach to get Ninject binding to work with an `HttpSelfHostServer` using the WebApi release version. The `CreateInstance` method is replaced by `DependencyResolver = new NinjectDependencyResolver(kernel);` – neontapir Aug 22 '13 at 14:58
4

In P5 you have to derive from WebApiConfiguration and use your derived configuration:

public class NinjectConfiguration : WebApiConfiguration
    {
        public NinjectConfiguration(IKernel kernel)
        {
            CreateInstance((t, i, m) =>
            {
                return kernel.Get(t);
            }); 
        }
    }
Alexander Zeitler
  • 11,919
  • 11
  • 81
  • 124
  • Thanks Alexander but where does the SetServiceInstanceProvider come form as VS says it cannot resolve it? Am I missing a namespace? Does my project need the MVC/WCF ninject extensions. I created a new class file called NinjectConfiguration and added the code you supplied. Also at what point would I load in my Ninject Serivce Module. In one of my standard WCF Services I call it like so: IKernel kernel = new StandardKernel(new NinjectServiceModule()); Thanks very much. – Cragly Sep 30 '11 at 15:29
  • Sorry, my mistake. I was referring to a wrong version of Web API from CodePlex. It is now called CreateInstance - updated the code above. – Alexander Zeitler Oct 01 '11 at 14:49
3

There are great answers to the question here but I would like to show you the way with default WebApi configuration:

    protected void Application_Start(object sender, EventArgs e) {

        RouteTable.Routes.SetDefaultHttpConfiguration(new Microsoft.ApplicationServer.Http.WebApiConfiguration() { 
            CreateInstance = (serviceType, context, request) => GetKernel().Get(serviceType)
        });

        RouteTable.Routes.MapServiceRoute<People.PeopleApi>("Api/People");
    }

    private IKernel GetKernel() { 

        IKernel kernel = new StandardKernel();

        kernel.Bind<People.Infrastructure.IPeopleRepository>().
            To<People.Models.PeopleRepository>();

        return kernel;
    }

The below blog post talks a little bit about Ninject integration on WCF Web API:

http://www.tugberkugurlu.com/archive/introduction-to-wcf-web-api-new-rest-face-ofnet

tugberk
  • 57,477
  • 67
  • 243
  • 335
  • This solution looks nice; the key is using the CreateInstance delegate property of HttpConfiguration (or the derived WebApiConfiguration, like you're using). However, I think your solution will new-up a Ninject kernel and set the binding on each request to that service type! Maybe better to new-up Ninject and set binding in Application_Start, store the reference in a private static field, use it to create service types, and dispose of it in Application_End. – Bellarmine Head Dec 16 '11 at 15:59
  • @AndrewWebb thanks for the suggestion. Can you provide a sample of what you are trying to explain? you can comment on my post : http://www.tugberkugurlu.com/archive/introduction-to-wcf-web-api-new-rest-face-ofnet or here. – tugberk Dec 16 '11 at 17:04
  • I tried adding a complete sample in a new answer, but the formatting was rubbish. Anyway, in the class in Global.asax.cs, add this field: private static IKernel _ninKernel; New-up a standard kernel in Application_Start and store the ref in this field, and set up your bindings. Dispose of this kernel object in Application_End:- _ninKernel.Dispose (); Use this field for newing-up service instances when you set your Http configuration:- CreateInstance = (serviceType, context, request) => _ninKernel.Get (serviceType), – Bellarmine Head Dec 19 '11 at 09:29
  • What worked for me is simply passing an instance of the NinjectWebApiConfiguration class to RouteTable.Routes.SetDefaultHttpConfiguration(): `RouteTable.Routes.SetDefaultHttpConfiguration(new NinjectWebApiConfiguration());` No need for the GetKernel function, which would create a new StandardKernel object each time a url that matches the route arrives. – dfjacobs Dec 30 '11 at 07:26
  • @dfjacobs I usually do it that way, too but the sake of simplicity here, I gave the simplest example. – tugberk Dec 30 '11 at 08:28