2012-02-23 3 views
11

Sono bloccato. Stavo usando il metodo descritto qui per wcf web api p6 Ninject working with WCF Web API Preview 5, tuttavia le cose sono un po 'diverse con l'implementazione di mvc nella beta. C'è un buon articolo qui http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver che parla della creazione del tuo risolutore di dipendenze personalizzato, tuttavia vorrei usare la stessa implementazione che sto usando per i miei controller di visualizzazione mvc ... ad es. Ninject. Ho provato anche alcune cose basate sull'esempio di IoC Unity nell'articolo, ma non è ancora stato fatto nulla. Qualsiasi aiuto che mi indichi la giusta direzione sarebbe molto apprezzato. Continuerò a scavare anche da solo. Grazie in anticipo!Utilizzo di Ninject con Asp.NET Web API Beta ApiController

Ecco dove sono. Stavo usando WebActivator per fare il bootstrap del codice, ma da allora l'ho scaricato su Application_Start() solo per prendere un'altra cosa dall'equazione.

protected void Application_Start() 
    { 
     var kernel = new StandardKernel(new MyNinjectModule()); 
     GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel)); 
    } 

E sto ricevendo il seguente errore:
Il tipo Ninject.Web.Mvc.NinjectDependencyResolver non sembra implementare Microsoft.Practices.ServiceLocation.IServiceLocator. Nome
parametro: commonServiceLocator

trovato la soluzione
forse c'è/sarà un modo più elegante, ma questo sta lavorando per me. Sto anche aggiungendo il mio gestore di messaggi personalizzati anche qui.

[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.AppStart.ApiBootstrapper), "Start")] 
namespace MyApp.AppStart 
{ 
    public class ApiBootstrapper 
    { 
     public static void Start() 
     { 
      var kernel = new StandardKernel(new MyNinjectModule()); 
      var resolver = new NinjectDependencyResolver(kernel); 
      GlobalConfiguration.Configuration.ServiceResolver.SetResolver(resolver.GetService, resolver.GetServices); 
      GlobalConfiguration.Configuration.MessageHandlers.Add(new ApiAuthHandler()); 
     } 
    } 
} 
+0

Questo è abbastanza bella soluzione: http://haacked.com/archive/2012/03/11/itrsquos- the-little-things-about-asp-net-mvc-4.aspx –

+0

controlla anche il pacchetto di @Remo Gloor qui sotto se vuoi usare gli stessi binding per entrambi i tipi di controller. Puoi trovarlo su github e installarlo da nuget. –

risposta

3

ho mai usato il WebAPI ma dal momento che la semantica del IDependencyResolver è esattamente la stessa di quella da MVC3 dovreste essere in grado di utilizzare la stessa applicazione: https://github.com/ninject/ninject.web.mvc/blob/master/mvc3/src/Ninject.Web.Mvc/NinjectDependencyResolver.cs

Update: Il Ninject.Web L'estensione .WebAPi aggiunge il supporto per ApiControllers

+2

Questa è una delle cose che ho provato, purtroppo senza gioia. ad esempio ServiceResolver.SetResolver (nuovo NinjectDependencyResolver (kernel)) produce il seguente errore: _Ninject.Web.Mvc.NinjectDependencyResolver non sembra implementare Microsoft.Practices.ServiceLocation.IServiceLocator_ –

+0

La soluzione era in definitiva utilizzare la classe ninjectdepencencyresolver, ho appena avuto utilizzare una firma di metodo alternativa su setresolver. Grazie per la risposta! –

0

Può sembrare sciocco, ma ti sei assicurato di avere un riferimento al pacchetto CommonServiceLocator/CommonServiceLocator.NinjectAdapter nuget o agli assembly associati. NinjectDependencyResolver potrebbe non essere in grado di risolvere il riferimento a IServiceLocator.

+0

Ho installato entrambi i pacchetti, ma ancora senza fortuna. Puoi vedere come il pacchetto di pacchetti ninject.mvc si collega automaticamente tramite un bootstrapper personalizzato usando webactivator ... ma deve essere al di fuori del ciclo di vita della richiesta di apicontroller poiché il reqeust non va direttamente al controller direttamente ... è stato creato per te dal quadro. –

+0

Il problema era che il mio codice si stava risolvendo con questa firma del metodo http://msdn.microsoft.com/en-us/library/hh835505(v=vs.108).aspx quando pensavo che usasse questo http://msdn.microsoft.com/en-us/library/hh835218(v=vs.108).aspx. Per fortuna c'è una terza opzione che aggira il problema del tipo. Grazie per la risposta Hamaze! –

1

Ho trovato la risposta e aggiornato la mia domanda sopra con la soluzione. La soluzione stessa era più o meno presente nell'articolo Using the Web API Dependency Resolver, dovevo solo continuare a fare i tweet con il ninject. Entrambe le risposte mi hanno aiutato a restringere rapidamente questo punto grazie a @Remo e @James.

+0

Puoi dare alcuni esempi di codice da quando si avvia l'associazione e il resto del codice dell'adattatore in uno? –

+1

@ShawnMclean Non sono sicuro di seguirti. Nella mia soluzione sopra, sto usando il pacchetto webactivator nuget su una classe personalizzata per registrare il risolutore delle dipendenze ninject con webapi (definendo i miei binding in una classe separata derivata da ninjectmodule). Puoi anche prendere lo stesso codice metodo e inserirlo nei tuoi metodi global.asax Application_Start(), preferisco semplicemente questo approccio bootstrap. C'è anche una risposta sopra che menziona la soluzione di Phil Haack, che essenzialmente ti permette di usare gli stessi binding sia per mvc che per web api. Comunque preferisco il mio metodo per il momento. –

0

Lo stesso codice funzionerà sia per MVC che per WebApi, tuttavia poiché WebApi è stato ispirato da MVC e gli assembly MVC non devono essere referenziati per utilizzare WebApi (o viceversa), c'è una buona dose di duplicazione del codice tra i due quadri. Se si desidera utilizzare MVC, le dipendenze verranno dallo System.Web.Mvc, se si desidera utilizzare WebApi si utilizzerà System.Web.Http. Se vuoi usare entrambi dovrai differenziare il tuo codice da usare quando, usando una risoluzione dello spazio dei nomi più esplicita.

Nel tuo caso il tuo problema è che MVC è arrivato per primo e la classe NinjectDependancyResolver eredita da System.Web.Mvc.IDependencyResolver. Dovrai creare un duplicato esatto della classe NinjectDependancyResolver e invece ereditare da System.Web.Http.IDependencyResolver. Usa QUESTA classe per configurare il tuo IoC e sarai a posto.

+0

grazie per la risposta! Questo è essenzialmente ciò che ho fatto nella mia risposta sopra a causa del problema di duplicazione che stai descrivendo. Tuttavia, poiché questo sovraccarico esiste su setresolver http://msdn.microsoft.com/en-us/library/hh834083(v=vs.108).aspx sono stato in grado di aggirare la creazione di un duplicatore di dipendenze ninject duplicato che implementa il sistema .web.http versione dell'interfaccia. Mi auguro che abbiano trovato un modo migliore per gestire questo però. Dovrei davvero essere in grado di usare lo stesso resolver di dipendenza per entrambi. –

0

Ho trovato una bella soluzione here.

È abbastanza facile se si sta già utilizzando il Ninject CommonServiceLocator/Bootstrapper:

private static IKernel CreateKernel() { 
    var kernel = new StandardKernel(); 
    RegisterServices(kernel); 

    GlobalConfiguration.Configuration.ServiceResolver 
     .SetResolver(new NinjectServiceLocator(kernel)); 
    return kernel; 
}