2012-11-14 9 views
5

Il mio progetto asp.net WebApi comprende più assembly per servizi, accesso principale e dati. Nel tentativo di utilizzare Ninject come mio contenitore DI nel progetto, ho aggiunto il pacchetto Ninject.Web.Common da NuGet. Poi, ho implementato IDependencyResolver come:Ninject 3 - BeginBlock() sovrascrive 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; 
    } 
} 

Ecco i miei Ninject.Web.Common.cs.

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

La mia domanda riguarda il codice in NinjectDependencyResolver -> metodo BeginScope(): return new NinjectDependencyScope (this.kernel.BeginBlock());

Mi piacerebbe avere i miei repository (implementati in WebApiTest.DataAccess.dll) su richiesta. Mi sono imbattuto in questo post da Nate Kohari. Mi rendo conto che il post è vecchio, ma la descrizione di Activation Blocks mi chiede se questa sia ancora l'implementazione corrente.

C'è un ultimo modo di gestire l'ambito in Ninject2, tramite blocchi di attivazione. I blocchi sono> un modo per sovrascrivere l'ambito dichiarato su un'associazione e associare invece> le istanze attivate al blocco stesso. ...

Quindi, qual è lo scopo effettivo dei miei repository?

Inoltre, sembra a me che l'uso di BeginBlock() è facoltativo ma quando rimuovo, la prima chiamata al controller riesce ma le chiamate successive buttare eccezione:

Ninject componente Icache No such componente è stato registrato nel contenitore del componente del kernel

PERCHÉ ??

risposta

13

Per ora utilizzare questo NinjectDependencyResolver e questo NinjectDependencyScope implementazioni

+0

Sto usando quelli. Cosa intendi esattamente? –

+0

Non lo sei. Guarda le implementazioni. Li abbiamo creati da questa discussione: https://github.com/ninject/Ninject.Web.WebApi/pull/1 –

+0

Ian, grazie. Non ho scoperto immediatamente i link nella tua risposta. La mia comprensione è corretta sul fatto che con la mia implementazione, BeginBlock() sovrascrive l'ambito su Singleton? –

1

Per poter utilizzare le dipendenze a richiesta portata non configurarli utilizzando Ninject di InRequestScope() ma li tirare fuori la richiesta utilizzando GetDependencyScope()

Ho messo insieme un post di blog su quello http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/

+0

Filip, grazie per il post sul blog. Veramente bello. Tuttavia, l'UoW è astratto rispetto al controller e non voglio portare il contesto fino in fondo. qualche idea? –

Problemi correlati