Pregunta

Estoy tratando de configurar Ninject por primera vez. Tengo una interfaz IRepository y una implementación de Repository. Estoy usando ASP.NET MVC, y estoy tratando de inyectar la implementación de esta manera:

public class HomeController : Controller
{
    [Inject] public IRepository<BlogPost> _repo { get; set; }

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        var b = new BlogPost
                    {
                        Title = "My First Blog Post!",
                        PostedDate = DateTime.Now,
                        Content = "Some text"
                    };

        _repo.Insert(b);

        return View();
    }

    // ... etc
}

Y aquí está Global.asax:

public class MvcApplication : NinjectHttpApplication
{
    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 = "" }  // Parameter defaults
        );

    }

    protected override void OnApplicationStarted()
    {
        RegisterRoutes(RouteTable.Routes);
    }

    protected override IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel(new BaseModule());
        return (kernel);
    }
}

Y aquí está la clase BaseModule:

   public class BaseModule : StandardModule
    {
        public override void Load()
        {
            Bind<IRepository<BlogPost>>().To<Repository<BlogPost>>();
        }
    }

Sin embargo, cuando busco la acción Index (), obtengo " Referencia de objeto no establecida en una instancia de un objeto " cuando intente usar _repo.Insert (b). ¿Qué estoy dejando afuera?

¿Fue útil?

Solución

Ninject 1.0 no tenía soporte MVC fuera de la caja. Hay varias formas de usar MVC con Ninject 1.0 dispersos por la web.

Recomiendo obtener el último código del tronco de Ninject, que incluye soporte MVC. Luego use lo siguiente como punto de partida para su aplicación:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using DemoApp.Models;
using Ninject.Core;
using Ninject.Framework.Mvc;

namespace DemoApp
{
    public class MvcApplication : NinjectHttpApplication
    {
        protected override 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 = "" }  // Parameter defaults
            );
        }

        protected override IKernel CreateKernel()
        {
            return new StandardKernel(new BaseModule(), new AutoControllerModule(Assembly.GetExecutingAssembly()));
        }
    }
}

Hay algunas cosas que destacar en comparación con su implementación original ...

  • Ninject tiene dos nombres de implementaciones NinjectHttpApplication: uno en Ninject.Framework.Web y uno en Ninject.Framework.Mvc. Pareces estar usando el primero como el segundo contiene un RegisterRoutes protegido () método.
  • Necesitas una manera de darle a Ninject un gancho en la creación del controlador, que se hace usando el ControllerBuilder. Ninject.Framework.Mvc.NinjectHttpApplication registra NinjectControllerFactory. Tendrá que proporcionarlo usted mismo si usa Ninject 1.0.
  • Necesita registrar sus controladores con el contenedor. ¡Podría hacerlo manualmente, pero usando el último código que proporciona y AutoControllerModule que registra automáticamente los controladores por usted!

Otros consejos

Debe agregar el AutoControllerModule a la lista de módulos que especifique al crear el núcleo, como se muestra a continuación:

protected override IKernel CreateKernel()
{
    IKernel kernel = new StandardKernel(
                         new BaseModule(), 
                         new AutoControllerModule(Assembly.GetExecutingAssembly())
                     );
    return (kernel);
}

El AutoControllerModule es parte del soporte de MVC en Ninject 1.x. Escanea el ensamblaje que proporciona a su constructor para las clases de controlador MVC y las vincula automáticamente. En el código, ha vinculado correctamente su repositorio, pero Ninject no se encarga de activar sus controladores. Para que su repositorio se inyecte en una instancia de su clase HomeController , Ninject debe encargarse de crear y activar los controladores. Sin el AutoControllerModule , MVC sigue a cargo de crear controladores; por lo tanto, Ninject nunca tiene la oportunidad de inyectar ningún miembro. Una vez que Ninject se encarga de crear y activar los controladores, la inyección se realizará como se esperaba.

Piense en el AutoControllerModule como encontrar todos los controladores y generar código como este (se utiliza HomeController como ejemplo):

Bind<HomeController>.ToSelf();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top