it-swarm.com.de

Konfigurieren von Ninject mit Asp.Net MVC & Web Api

ich habe mein Projekt mit Ninject IoC.
Mein Projekt hat regelmäßige Asp.Net MVC Controller und Web Api Steuerungen. Jetzt arbeitet Ninject mit Web Api aber Ninject funktioniert nicht mit regulären Asp.MVC Steuerungen.
Meine regulärer MVC-Controller Implementierung;

public class GalleryController : BaseController
{
    public GalleryController(IUow uow)
    {
        Uow = uow;
    }
    ........
}

Fehler bei der Verwendung mit regulären Controller

An error occurred when trying to create a controller of type 'Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]

Wenn ich jedoch den gleichen Code mit Web Api, versuche, funktioniert es

public class GalleryController : BaseApiController
{
    public GalleryController(IUow uow)
    {
        Uow = uow;
    }
    ......
}

meine Schnittstelle, die Differenz-Repositorys enthält (das Factory-Muster)

public interface IUow
{
    // Save pending changes to the data store.
    void Commit();

    //Repositoryries
    IRepository<Gallery> Gallery { get; }
    IMenuRepository Menus { get; }
}

NinjectDependencyScope class;

public class NinjectDependencyScope : IDependencyScope
{
    private IResolutionRoot resolver;

    internal NinjectDependencyScope(IResolutionRoot resolver)
    {
        Contract.Assert(resolver != null);

        this.resolver = resolver;
    }

    public void Dispose()
    {
        var disposable = resolver as IDisposable;
        if (disposable != null)
            disposable.Dispose();

        resolver = null;
    }

    public object GetService(Type serviceType)
    {
        if (resolver == null)
            throw new ObjectDisposedException("this", "This scope has already been disposed");

        return resolver.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        if (resolver == null)
            throw new ObjectDisposedException("this", "This scope has already been disposed");

        return resolver.GetAll(serviceType);
    }
}

NinjectDependencyResolver class;

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
    private IKernel kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        this.kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NinjectDependencyScope(kernel.BeginBlock());
    }
}

Ninject Konfiguration für Global.asax;

public class IocConfig
{
    public static void RegisterIoc(HttpConfiguration config)
    {
        var kernel = new StandardKernel(); // Ninject IoC
        //kernel.Load(Assembly.GetExecutingAssembly()); //only required for asp.net mvc (not for webapi)
        // These registrations are "per instance request".
        // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/

        kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
            .InSingletonScope();

        kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
        kernel.Bind<IUow>().To<Uow>();

        // Tell WebApi how to use our Ninject IoC
        config.DependencyResolver = new NinjectDependencyResolver(kernel);
    }
}

Global.asax

protected void Application_Start()
{

    // Tell WebApi to use our custom Ioc (Ninject)
    IocConfig.RegisterIoc(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration);
    AreaRegistration.RegisterAllAreas();
}
37
DotNet Dreamer

Nachdem wir viel gesucht haben, stellt sich heraus, dass wir Ninject nicht mit Web-API und regulärem MVC verwenden können. Ich meine, wir müssen die Repositories separat konfigurieren.

Ich habe dann einen netten Artikel gefunden, in dem erklärt wird, wie Sie Ninject mit asp.net mvc & web api verwenden können: http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net- mvc4-and-webapi-us

Und jetzt verstehe ich den Fehler nicht und es funktioniert: D

Update 1:

Versuchen Sie auch Folgendes: Schreiben einer einfachen Implementierung der Abhängigkeitsinjektion in die MVC 4-Web-API mit .NET Framework 4.5

13
DotNet Dreamer

Ich habe einige Listen geschrieben, um Ninject mit MVC und Web Api zu konfigurieren. Fügen Sie einfach die Datei (en) hinzu:

Um Bindungen für konkrete Typen hinzuzufügen, fügen Sie diese einfach in die Load() -Methode des MainModule ein. Sie können so viele Module erstellen, wie Sie möchten, um die Bindungen zu organisieren. Sie müssen sie jedoch auch dem Array hinzufügen, das in der Eigenschaft Modules zurückgegeben wird.

Fügen Sie dann der Application_Start() -Methode hinzu

  • NinjectContainer.RegisterModules(NinjectModules.Modules) (für MVC)
  • NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules) (für WebApi)

Beachten Sie, dass Sie für die MVC- und die WebApi-Registrierung dasselbe NinjectModules.Modules Verwenden können. Ich habe es nur aus Gründen der Klarheit getrennt

[~ # ~] Update [~ # ~] : Denken Sie daran, NinjectWebCommon.cs aus Ihrem Projekt zu entfernen, wenn ein neuer Kernel zur Laufzeit geladen und gebootet wird ist leider nur für mvc.

[~ # ~] Update [~ # ~] : Sie können auch verwenden

  • NinjectContainer.RegisterAssembly() (für MVC)
  • NinjectHttpContainer.RegisterAssembly() (für WebApi)

Dadurch wird Ihre aktuelle Baugruppe nach allen Modulen durchsucht. Auf diese Weise können Sie Ihre Module an einer beliebigen Stelle in Ihrem Projekt platzieren und es wird registriert

34
Ody

Mit MVC 5 und Web API 2.2 habe ich dieses Problem behoben, indem ich sichergestellt habe, dass die folgenden NuGet-Pakete enthalten sind:

  • Ninject.MVC5
  • Ninject.Web.WebApi.WebHost für die Web-API

Dadurch wurden andere Ninject-Abhängigkeiten installiert und ich konnte RegisterServices bis NinjectWebCommon.cs.

15
DigitalDan

Hier ist die einfache Lösung, die für mich gut funktioniert:

  1. Erstellen Sie in Visual Studio ein neues Webanwendungsprojekt mit dem Namen DemoApp und stellen Sie sicher, dass Sie Leere Vorlage mit MVC- und Web-API-Referenzen ausgewählt haben: enter image description here
  2. Führen Sie in der Package Manager-Konsole nacheinander Folgendes aus:

    Installationspaket Ninject

    Installationspaket Ninject.MVC5

  3. Fügen Sie NinjectDependencyResolver.cs zum IoC-Ordner hinzu:

    using Ninject;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http.Dependencies;
    
    namespace DemoApp.IoC
    {
        public class NinjectDependencyResolver : IDependencyResolver, System.Web.Mvc.IDependencyResolver
        {
            private readonly IKernel kernel;
    
            public NinjectDependencyResolver(IKernel kernel)
            {
                this.kernel = kernel;
            }
    
            public IDependencyScope BeginScope()
            {
                return this;
            }
    
            public object GetService(Type serviceType)
            {
                return kernel.TryGet(serviceType);
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
            {
                return kernel.GetAll(serviceType);
            }
    
            public void Dispose() { } //it is not necessary to implement any dispose logic here
        }
    }
    
  4. Nehmen Sie die folgenden Änderungen in App_Start/NinjectWebCommon.cs vor:

    • Fügen Sie diese Zeilen in die CreateKernel-Methode ein:

      NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver (Kernel); DependencyResolver.SetResolver (ninjectResolver); // MVC GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API

    • Fügen Sie Ihre Bindungen in der RegisterServices-Methode wie folgt hinzu:

      kernel.Bind <IHelloService> (). To <HelloService> ();

Jetzt sollte NinjectWebCommon.cs so aussehen:

[Assembly: WebActivatorEx.PreApplicationStartMethod(typeof(DemoApp.App_Start.NinjectWebCommon), "Start")]
[Assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(DemoApp.App_Start.NinjectWebCommon), "Stop")]

namespace DemoApp.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;
    using DemoApp.IoC;
    using System.Web.Mvc;
    using System.Web.Http;
    using DemoApp.Config;

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);

                NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel);
                DependencyResolver.SetResolver(ninjectResolver); //MVC
                GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; //Web API

                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IHelloService>().To<HelloService>();
        }        
    }
}
  1. Um das Beispiel zu vervollständigen, fügen Sie einige Mvc- und Api-Controller und Code für IHelloService, HelloService hinzu:

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DemoApp.Config;
namespace DemoApp.Controllers
{
    public class HomeController : Controller
    {
        private IHelloService helloService;

        public HomeController(IHelloService helloService)
        {
            this.helloService = helloService;
        }

        // GET: /Home/
        public string Index()
        {
            return "home/index: " + helloService.GetMessage();
        }
    }
}

UserController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using DemoApp.Config;
namespace DemoApp.Controllers
{
    public class UserController : ApiController
    {
        private IHelloService helloService;

        public UserController(IHelloService helloService)
        {
            this.helloService = helloService;
        }

        [HttpGet]
        public string Data()
        {
            return "api/user/data: " + helloService.GetMessage();
        }
    }
}

IHelloService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
    public interface IHelloService
    {
       string GetMessage();
    }
}

HelloService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
    public class HelloService : IHelloService
    {
        public string GetMessage()
        {
            return "Hi";
        }
    }
}
  1. Die endgültige Struktur sollte wie folgt aussehen: enter image description here

    Führen Sie nun einige Tests im Browser durch. Für mich war es:

    http: // localhost: 51156/home/index

    http: // localhost: 51156/api/user/data

Und das ist es.

6
r23

Ich denke, das Problem ist, dass Sie keine ControllerFactory registrieren, die Ninject verwendet, um die Controller zu erstellen (und ihre Abhängigkeiten aufzulösen). Haben Sie bereits versucht, Ihre eigene ControllerFactory zu implementieren? Siehe auch hier http://bubblogging.wordpress.com/2012/06/04/mvc-controller-factory-ninject/ .

0
PermaFrost

Hierfür gibt es eine elegantere Lösung von Nenad - ich habe 3 zusätzliche Stunden gebraucht, weil ich zuerst versucht habe, die Lösungen zu implementieren, die mit der vorhandenen Infrastruktur in Konflikt stehen. Es ist als Antwort auf eine andere Stapelüberlauf-Frage . Ich kopiere diese Antwort hier, nur für den Fall, dass es anderen hilft, meine verlorene Zeit zu sparen.


Es gibt eine Möglichkeit, denselben Container für MVC und die ASP.NET-Web-API freizugeben. Sie müssen nur beide Schnittstellen implementieren.

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
   {
       private readonly IKernel kernel;

       public NinjectDependencyResolver(IKernel kernel)
           : base(kernel)
       {
           this.kernel = kernel;
       }

       public IDependencyScope BeginScope()
       {
           return new NinjectDependencyScope(this.kernel.BeginBlock());
       }
   }

In diesem Artikel finden Sie eine Lösung: Einfache Methode zum Freigeben von Abhängigkeitsauflösern zwischen MVC und Web-API

0
user3141326