System.InvalidOperationException:Der Dienst für den Typ konnte beim Aktivierungsversuch nicht aufgelöst werden

System.InvalidOperationException:Der Dienst für den Typ konnte beim Aktivierungsversuch nicht aufgelöst werden

Wenn die integrierte Abhängigkeitsinjektionsfunktion versucht, einen Typ zu erstellen, versucht sie, alle Konstruktorparameter aufzulösen. Wenn es einen der Parameter nicht auflösen kann, wird es eine Variante einer dieser Ausnahmen auslösen:

  • InvalidOperationException:Dienst für Typ kann nicht aufgelöst werden, während versucht wird, zu aktivieren .
  • ArgumentException:Der Implementierungstyp „Typname“ für den Diensttyp „Typname“ kann nicht instanziiert werden .

Der Fehler, den Sie erhalten, hängt davon ab, wie Sie die Registrierung durchführen. Zuerst zeige ich die Lösung. Dann zeige ich ein paar verschiedene Variationen des Problems.

Lösung

Die einfachste Lösung besteht darin, den Typ explizit zu registrieren. Wenn dieser Typ einen primitiven Konstruktorparameter hat, teilen Sie ihm auch genau mit, wie der Typ erstellt werden soll.

Hier ist ein Beispiel. Nehmen wir an, Sie haben eine Klasse namens JsonLogger mit dem folgenden Konstruktor:

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

Sie müssen diesen Typ explizit registrieren und angeben, wie er erstellt wird:

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)

Kapseln Sie die primitiven Parameter

Wenn Sie eine Mischung aus primitiven Parametern haben, die nicht automatisch aufgelöst werden können, und Typen, die aufgelöst werden können, ziehen Sie in Betracht, die primitiven Parameter in einer Klasse zu kapseln. Andernfalls müssten Sie IServiceProvider.GetService() für alle Typen, die aufgelöst werden können, wiederholt aufrufen, wenn Sie ihm mitteilen, wie das Objekt erstellt werden soll.

Hier ist ein Beispiel. Angenommen, Sie haben den folgenden Konstruktor:

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

Kapseln Sie die beiden primitiven Parameter:

//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)

Registrieren Sie dann alle Typen:

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)

Beispiel für Ursache 1 – services.AddSingleton()

Wenn Sie den Typ registrieren und ihm mitteilen, welchen konkreten Typ Sie wollen, und dieser Typ einen primitiven Parameter wie diesen hat:

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

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

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

Dann erhalten Sie diese Ausnahme:

Sie müssen ihm mitteilen, wie der Typ konstruiert werden soll, da er nicht weiß, wie er den primitiven Konstruktorparameter auflösen soll.

Beispiel für Ursache 2 – services.AddSingleton

Wenn Sie versuchen, den Typ zu registrieren, ohne ihm explizit mitzuteilen, in welchen konkreten Typ er aufgelöst werden soll, etwa so:

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

		services.AddSingleton<ILogger>();
	}

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

Dann erhalten Sie die folgende Ausnahme:

Beispiel für Ursache 3 – Wenn Sie den Typ nicht registrieren

Nehmen wir an, Sie haben einen Controller, der von ILogger abhängig ist:

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


	private readonly ILogger _logger;

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

Wenn Sie den Typ, von dem er abhängig ist (ILogger), nicht registrieren, erhalten Sie die folgende Ausnahme:

Hinweis:Dies ist nicht Microsoft.Extensions.Logging.ILogger.