System.InvalidOperationException:impossibile risolvere il servizio per il tipo durante il tentativo di attivazione

System.InvalidOperationException:impossibile risolvere il servizio per il tipo durante il tentativo di attivazione

Quando la funzionalità di inserimento delle dipendenze incorporata tenta di creare un tipo, tenta di risolvere tutti i parametri del costruttore. Se non riesce a risolvere uno dei parametri, genererà una variazione di una di queste eccezioni:

  • InvalidOperationException:impossibile risolvere il servizio per il tipo durante il tentativo di attivare .
  • ArgumentException:impossibile creare un'istanza del tipo di implementazione "Nome del tipo" per il tipo di servizio "Nome del tipo" .

L'errore che ricevi dipenderà da come stai effettuando la registrazione. Per prima cosa, mostrerò la soluzione. Quindi mostrerò alcune diverse varianti del problema.

Soluzione

La soluzione più semplice è registrare in modo esplicito il tipo. Se quel tipo ha un parametro del costruttore primitivo, spiegagli esattamente come creare il tipo.

Ecco un esempio. Supponiamo che tu abbia una classe chiamata JsonLogger con il seguente costruttore:

 public JsonLogger(string source)
Code language: C# (cs)

Dovresti registrare esplicitamente questo tipo e specificare come crearlo:

public class Startup
{
	
	public void ConfigureServices(IServiceCollection services)
	{
		//rest of ConfigureServices()

		services.AddSingleton<ILogger>(_ => new JsonLogger("web app"));
	}

	//rest of Startup class
}
Code language: C# (cs)

Incapsula i parametri primitivi

Quando hai un mix di parametri primitivi che non possono essere risolti automaticamente e tipi che possono essere risolti, considera l'idea di incapsulare i parametri primitivi in ​​una classe. Altrimenti, quando gli dici come creare l'oggetto, dovresti chiamare ripetutamente IServiceProvider.GetService() per tutti i tipi che possono essere risolti.

Ecco un esempio. Supponiamo che tu abbia il seguente costruttore:

public JsonLogger(string source, bool debugEnabled, IUtility utility)
Code language: C# (cs)

Incapsula i due parametri primitivi:

//Pull the primitives into a new class
public class LoggerConfig
{
	public string Source { get; set; }
	public bool DebugEnabled { get; set; }
}

//Change the parameter to use the object
public JsonLogger(LoggerConfig config, IUtility utility)
Code language: C# (cs)

Quindi registra tutti i tipi:

public class Startup
{
	public void ConfigureServices(IServiceCollection services)
	{
		//rest of method
		
		services.AddSingleton<IUtility, JsonUtility>();
		services.AddSingleton<LoggerConfig>(_ => new LoggerConfig()
		{
			Source = "web app",
			DebugEnabled = true
		});

		services.AddSingleton<ILogger, JsonLogger>();
	}
	
	//rest of class
}
Code language: C# (cs)

Causa 1 esempio:services.AddSingleton()

Quando registri il tipo e gli dici quale tipo concreto vuoi, e quel tipo ha un parametro primitivo, come questo:

public class Startup
{
	
	public void ConfigureServices(IServiceCollection services)
	{
		//rest of ConfigureServices()

		services.AddSingleton<ILogger, JsonLogger>();
	}

	//rest of Startup class
}
Code language: C# (cs)

Quindi otterrai questa eccezione:

Devi dirgli come costruire il tipo, poiché non sa come risolvere il parametro del costruttore primitivo.

Causa 2 esempio – services.AddSingleton

Quando provi a registrare il tipo senza dirgli esplicitamente a quale tipo concreto risolvere, in questo modo:

public class Startup
{
	
	public void ConfigureServices(IServiceCollection services)
	{
		//rest of ConfigureServices()

		services.AddSingleton<ILogger>();
	}

	//rest of Startup class
}
Code language: C# (cs)

Quindi otterrai la seguente eccezione:

Causa 3 esempio – Quando non registri il tipo

Supponiamo che tu abbia un controller che dipende da ILogger:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{


	private readonly ILogger _logger;

	public WeatherForecastController(ILogger logger)
	{
		_logger = logger;
	}
	
	//rest of class
}
Code language: C# (cs)

Se non registri il tipo da cui dipende (ILogger), otterrai la seguente eccezione:

Nota:questo non è Microsoft.Extensions.Logging.ILogger.