Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebAPI with Ninject

I'm having a trouble, making Ninject and WebAPI.All working together. I'll be more specific:
First, I played around with WebApi.All package and looks like it works fine to me.
Second, I added to RegisterRoutes in Global.asax next line:

routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));

So the final result was:


public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

}

Everything seems to be fine, but when I'm trying to redirect user to a specific action, something like:

return RedirectToAction("Index", "Home");

Url in browser is localhost:789/api/contacts?action=Index&controller=Home Which is not good. I swaped lines in RegisterRoute and now it looks:


public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );
            routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));
            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

        }

Now the redirection works fine, but when I try to access to my API actions, I get error telling me that Ninject couldn't return controller "api" which is absolutely logical, I don't have such controller.

I did search some info how to make Ninject work with WebApi, but everything I found was only for MVC4 or .Net 4.5. By the technical issues I can't move my project to a new platform, so I need to find a working solution for this versions.

This answer looked like a working solution, but when I'm trying to launch project I get compiler error in line

CreateInstance = (serviceType, context, request) => kernel.Get(serviceType);

telling me:

System.Net.Http.HttpRequestMessage is defined in an assembly that is not referenced

and something about adding refference in assembly

System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

I have no Idea what to do next, I couldn't find any useful info about ninject with webapi on .NET 4 and MVC3. Any help would be appreciated.

like image 887
DmitryL Avatar asked Oct 21 '12 09:10

DmitryL


People also ask

What is ninject Web API?

NInject is a popular IOC container that can be used to inject dependencies in your WebAPI controllers easily. IDG. Dependency injection is a software design pattern that helps you to build pluggable implementations in your application using loosely coupled, testable components.

Why Ninject is used?

Ninject is a lightweight dependency injection framework for . NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner.

What is dependency Injection Web API?

What is Dependency Injection? A dependency is any object that another object requires. For example, it's common to define a repository that handles data access. Let's illustrate with an example.

Is ninject open source?

Ninject is and will always be free for both personal and commercial projects. It's also open source, so you can fork the code and make any changes you like.


Video Answer


1 Answers

Here are a couple of steps I have compiled for you that should get you started:

  1. Create a new ASP.NET MVC 3 project using the Internet Template
  2. Install the following 2 NuGets: Microsoft.AspNet.WebApi and Ninject.MVC3
  3. Define an interface:

    public interface IRepository
    {
        string GetData();
    }
    
  4. And an implementation:

    public class InMemoryRepository : IRepository
    {
        public string GetData()
        {
            return "this is the data";
        }
    }
    
  5. Add an API controller:

    public class ValuesController : ApiController
    {
        private readonly IRepository _repo;
        public ValuesController(IRepository repo)
        {
            _repo = repo;
        }
    
        public string Get()
        {
            return _repo.GetData();
        }
    }
    
  6. Register an API Route in your Application_Start:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        GlobalConfiguration.Configuration.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    
        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
    
  7. Add a custom Web API Dependency Resolver using Ninject:

    public class LocalNinjectDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
    {
        private readonly IKernel _kernel;
    
        public LocalNinjectDependencyResolver(IKernel kernel)
        {
            _kernel = kernel;
        }
    
        public System.Web.Http.Dependencies.IDependencyScope BeginScope()
        {
            return this;
        }
    
        public object GetService(Type serviceType)
        {
            return _kernel.TryGet(serviceType);
        }
    
        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return _kernel.GetAll(serviceType);
            }
            catch (Exception)
            {
                return new List<object>();
            }
        }
    
        public void Dispose()
        {
        }
    }
    
  8. Register the custom dependency resolver inside the Create method (~/App_Start/NinjectWebCommon.cs):

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
    
        RegisterServices(kernel);
    
        GlobalConfiguration.Configuration.DependencyResolver = new LocalNinjectDependencyResolver(kernel); 
        return kernel;
    }
    
  9. Configure the kernel inside the RegisterServices method (~/App_Start/NinjectWebCommon.cs):

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IRepository>().To<InMemoryRepository>();
    }        
    
  10. Run the application and navigate to /api/values.

like image 136
Darin Dimitrov Avatar answered Oct 14 '22 03:10

Darin Dimitrov