2012-11-14 4 views
5

Mein asp.net WebApi Projekt besteht aus mehreren Assemblies für Services, Core und Data Access. In einem Versuch, Ninject als meinen DI-Container in dem Projekt zu verwenden, habe ich das Ninject.Web.Common-Paket von NuGet hinzugefügt. Dann, Implementiert ich IDependencyResolver als:Ninject 3 - Überschreibt BeginBlock() InRequestScope in asp.net WebAPI?

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

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

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

public class NinjectDependencyScope : IDependencyScope 
{ 
    IResolutionRoot resolver; 

    public NinjectDependencyScope(IResolutionRoot resolver) 
    { 
     this.resolver = resolver; 
    } 

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

     var resolved = this.resolver.Get(serviceType); 
     return resolved; 
    } 

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

     return this.resolver.GetAll(serviceType); 
    } 

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

     resolver = null; 
    } 
} 

Hier mein Ninject.Web.Common.cs ist.

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(); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 
     RegisterServices(kernel); 

     GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); 
     return kernel; 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind(x => 
      x.FromAssembliesMatching("WebApiTest.DataAccess.dll") 
      .SelectAllClasses() 
      .BindAllInterfaces() 
      .Configure(config => config.InRequestScope())); 

     kernel.Bind(x => 
      x.FromAssembliesMatching("WebApiTest.*.dll") 
      .SelectAllClasses() 
      .BindAllInterfaces() 
      .Configure(config => config.InTransientScope())); 
    }   
} 

Meine Frage ist, über den Code in NinjectDependencyResolver -> BeginScope() -Methode: return new NinjectDependencyScope (this.kernel.BeginBlock());

Ich möchte meine Repositories (implementiert in WebApiTest.DataAccess.dll) Anfrage Bereich sein. Ich bin auf dieses post von Nate Kohari gestoßen. Ich weiß, dass der Beitrag alt ist, aber die Beschreibung über Aktivierungsblöcke lässt mich fragen, ob das immer noch die aktuelle Implementierung ist.

Es gibt eine letzte Möglichkeit, den Umfang in Ninject2 durch Aktivierungsblöcke zu behandeln. Blöcke sind> eine Möglichkeit, den Gültigkeitsbereich zu überschreiben, der für eine Bindung deklariert wurde, und ordnen stattdessen die aktivierten Instanzen dem Block selbst zu. ...

Also, Was ist der tatsächliche Umfang meiner Repositories?

Auch klingt für mich, dass die Verwendung von BeginBlock() optional ist, aber wenn ich es zu entfernen, der erste Aufruf an die Steuerung gelingt es aber alle nachfolgenden Anrufe werfen Ausnahme:

Ninject Komponente ICache No such Komponente wurde im Komponentencontainer des Kernels registriert

WARUM ??

Antwort

13

Vorerst verwenden diese NinjectDependencyResolver und diese NinjectDependencyScope Implementierungen

+0

Ich benutze diese. Was genau meinst du? –

+0

Sie sind nicht. Sehen Sie sich die Implementierungen an. Wir haben sie aus diesem Thread erstellt: https://github.com/ninject/Ninject.Web.WebApi/pull/1 –

+0

Ian, danke. Habe die Links in deiner Antwort nicht sofort entdeckt. Ist mein Verständnis korrekt, dass der BeginBlock() den Bereich mit meiner Implementierung zu Singleton überschreibt? –

1

Um Abhängigkeiten in Anforderungsbereich verwenden Sie sie nicht Ninject der InRequestScope() mit eingerichtet, aber ziehen sie aus dem Antrag mit GetDependencyScope()

ich zusammen ein Blogpost über das http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/

+0

Filip, danke für den Blogbeitrag. Wirklich nett. Die UoW wird jedoch vom Controller weg abstrahiert und ich möchte den Kontext nicht vollständig durchziehen. Irgendwelche Gedanken? –

Verwandte Themen