Ho implementato il middleware di ASP.NET Core personalizzato che utilizza il contesto del database come dipendenza. A volte genera la seguente eccezione per la prima richiesta proveniente dall'API:
Si è verificata un'eccezione non gestita durante l'esecuzione della richiesta. System.InvalidOperationException: è stato effettuato un tentativo di utilizzare il contesto durante la configurazione. Un'istanza di DbContext non può essere utilizzata all'interno di OnConfiguring poiché è ancora in fase di configurazione a questo punto. Questo può accadere se viene avviata una seconda operazione in questo contesto prima che una precedente operazione sia stata completata. Non è garantito che tutti i membri di istanza siano thread-safe
Potrei riprodurlo solo quando l'API è stata chiamata da SPA. Quando ho chiamato API da Swagger, tutto andava bene. Cambiare ordine di middleware non ha aiutato. Dopo aver scavato, mi sono reso conto che il middleware è stato istanziato una volta per applicazione mentre il contesto del database aveva una vita utile. Quindi forse il problema era di iniettare il mio contesto di database direttamente nel costruttore del middleware. Ho corretto il mio codice rimuovendo l'iniezione del contesto del database dal costruttore e inserendolo direttamente nel metodo InvokeAsync
. Questo ha aiutato e l'eccezione è andata.
Anche se ho risolto il mio problema, non ho ancora capito bene come funzionasse. Per quanto ne so, il contesto del database EF.Core per impostazione predefinita è registrato con durata scoped cosa in termini di applicazione ASP.NET Core significa che il nuovo contesto viene istanziato per ogni nuova richiesta e disposto al suo completamento. Poiché ho iniettato il contesto del database nel costruttore del middleware, dovrebbe essere stato eliminato subito dopo la prima richiesta e questa eccezione o un'altra che dice che sta tentando di utilizzare il contesto già disposto dovrebbe essere stata generata. Inoltre, non è assolutamente chiaro per quale motivo questo errore si è verificato solo quando API è stata chiamata da SPA mentre funzionava correttamente per tutte le richieste Swagger.
Sembra che l'abbia capito. Non ho detto che utilizzo il fornitore di servizi Autofac invece del provider di servizi predefinito nella mia applicazione, che in effetti valeva la pena menzionarlo. Secondo la documentazione di ASP.NET Core
Il provider di servizi predefinito nell'ambiente di sviluppo esegue controlli per verificare che:
- I servizi individuati non vengono risolti direttamente o indirettamente dal provider del servizio root.
- I servizi scoped non vengono iniettati direttamente o indirettamente in singleton.
Apparentemente il fornitore di servizi di Autofac non esegue tali controlli in modo da consentire l'inserimento di servizi con scope dal fornitore di servizi di root. E secondo la documentazione
La durata del provider di servizi di root corrisponde alla durata dell'app / server quando il provider inizia con l'app e viene eliminata quando l'app viene arrestata.
Questo è il motivo per cui la mia applicazione ha funzionato come previsto, anche se ho inserito il servizio con scope in singleton. Ha utilizzato l'istanza di DbContext
risolta dal provider del servizio di root e talvolta ho potuto ottenere tale situazione quando ho tentato di eseguire una query sul database prima che il contesto fosse effettivamente inizializzato. Questo spiega la natura sporadica di questo problema.