Domanda

Sto provando a configurare Ninject per la prima volta. Ho un'interfaccia IRepository e un'implementazione del Repository. Sto usando ASP.NET MVC e sto cercando di iniettare l'implementazione in questo modo:

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
}

Ed ecco 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);
    }
}

Ed ecco la classe BaseModule:

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

Quando cerco l'azione Index (), tuttavia, ottengo " Riferimento oggetto non impostato su un'istanza di un oggetto " quando si tenta di utilizzare _repo.Insert (b). Cosa sto lasciando fuori?

È stato utile?

Soluzione

Ninject 1.0 non aveva il supporto MVC pronto all'uso. Esistono vari modi per utilizzare MVC con Ninject 1.0 sparsi sul Web.

Consiglio di ottenere l'ultimo codice dal trunk Ninject, che include il supporto MVC. Quindi utilizzare quanto segue come punto di partenza per l'applicazione:

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()));
        }
    }
}

Ci sono alcune cose da evidenziare rispetto all'implementazione originale ...

  • Ninject ha due nomi delle implementazioni NinjectHttpApplication - uno in Ninject.Framework.Web e uno in Ninject.Framework.Mvc. Sembra che tu usando il primo come il successivo contiene un RegisterRoutes protetto () metodo.
  • È necessario un modo per dare a Ninject un gancio nella creazione del controller, che viene eseguita utilizzando ControllerBuilder. Ninject.Framework.Mvc.NinjectHttpApplication registra NinjectControllerFactory. Dovrai fornirlo tu stesso se usi Ninject 1.0.
  • È necessario registrare i controller con il contenitore. Potresti farlo manualmente, ma utilizzando l'ultimo codice fornisce e AutoControllerModule che registra automaticamente i controller per te!

Altri suggerimenti

Devi aggiungere il AutoControllerModule all'elenco dei moduli che specifichi durante la creazione del kernel, mostra sotto:

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

Il AutoControllerModule fa parte del supporto MVC in Ninject 1.x. Esegue la scansione dell'assembly fornito al costruttore per le classi di controller MVC e li lega automaticamente. Nel codice, hai associato correttamente il tuo repository, ma Ninject non ha il compito di attivare i tuoi controller. Affinché il tuo repository venga iniettato in un'istanza della tua classe HomeController , Ninject deve essere responsabile della creazione e dell'attivazione dei controller. Senza il modulo AutoController , MVC rimane responsabile della creazione dei controller; pertanto, Ninject non ha mai la possibilità di iniettare alcun membro. Una volta che Ninject è incaricato di creare e attivare i controller, l'iniezione avverrà come previsto.

Pensa al modulo AutoController come trovare tutti i controller e generare codice come questo (HomeController usato come esempio):

Bind<HomeController>.ToSelf();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top