Simple Injector non è in grado di iniettare dipendenze nei controller API Web

Simple Injector non è in grado di iniettare dipendenze nei controller API Web

TLTR: il problema è causato dal modo implicito in cui l'API Web gestisce la risoluzione dei tipi di controller; registra i tuoi controller API Web in modo esplicito e vedrai dove si trova il problema.

Ecco un passo dopo passo cosa sta succedendo sotto le coperte:

  1. Il System.Web.Http.DefaultHttpControllerActivator chiama il SimpleInjectorWebApiDependencyResolver e richiede la creazione di un controller API.
  2. SimpleInjectorWebApiDependencyResolver inoltra la chiamata al SimpleInjector.Container esempio.
  3. Quel Container istanza, tuttavia, non ha registrazioni esplicite per quel controller API (dal momento che hai fornito un contenitore vuoto al risolutore).
  4. Dato che non esiste una registrazione esplicita, il contenitore tenta di eseguire una registrazione dell'ultimo minuto per quel tipo.
  5. Quel tipo di Controller dipende però dalle interfacce che non possono essere risolte perché non sono registrate nel container (ricorda, il tuo container è vuoto).
  6. Sebbene il contenitore normalmente genererebbe un'eccezione, in questo caso viene restituito null, poiché il tipo viene richiesto tramite IServiceProvider.GetService metodo e il tipo non è stato registrato in modo esplicito.
  7. Il SimpleInjectorWebApiDependencyResolver è GetService il metodo restituirà null inoltre, poiché è per definizione che dovrebbe restituire null; Dovrebbe restituire null quando non esiste alcuna registrazione (che attualmente è il caso).
  8. Dal DependencyResolver restituito null, DefaultHttpControllerActivator ritornerà al suo comportamento predefinito, il che significa creare quel tipo stesso, ma ciò richiede che il controller disponga di un costruttore predefinito.

Per farla breve, il problema è causato dal modo implicito in cui l'API Web gestisce la risoluzione dei tipi di controller.

Quindi la soluzione qui è:

  1. Avere un solo Container nella tua applicazione web. Ciò previene ogni tipo di problema e complicazione della tua configurazione.
  2. Registra tutti i Web API Controller in modo esplicito nel contenitore. La registrazione esplicita dei controller garantirà che Simple Injector genererà un'eccezione quando non è possibile risolvere un controller. Inoltre, questo ti permette di chiamare il container.Verify() che farà fallire l'applicazione durante l'avvio quando la configurazione non è valida (una configurazione verificabile è importante). E questo ti permette anche di diagnosticare la configurazione che ti dà ancora più sicurezza sulla correttezza della tua configurazione.

Il mio consiglio è di inserire MVC e Web API nel proprio progetto. Questo renderà le cose molto più semplici.

La registrazione di tutti i controller dell'API Web può essere eseguita con il seguente codice:

container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

AGGIORNAMENTO:

Poiché questo errore è così comune, versioni più recenti di SimpleInjectorWebApiDependencyResolver la classe semplicemente mai restituisci null quando viene richiesto un tipo di controller. Invece genererà un errore descrittivo. Per questo motivo non dovresti mai più vedere errori, purché utilizzi il SimpleInjectorWebApiDependencyResolver ufficiale .