System.InvalidOperationException:no se puede resolver el servicio para el tipo al intentar activar

System.InvalidOperationException:no se puede resolver el servicio para el tipo al intentar activar

Cuando la funcionalidad de inyección de dependencia integrada intenta crear un tipo, intenta resolver todos los parámetros del constructor. Si no puede resolver uno de los parámetros, generará una variación de una de estas excepciones:

  • InvalidOperationException:No se pudo resolver el servicio para el tipo al intentar activar .
  • ArgumentException:no se puede crear una instancia del tipo de implementación 'Nombre de tipo' para el tipo de servicio 'Nombre de tipo' .

El error que obtenga dependerá de cómo esté realizando el registro. Primero, mostraré la solución. Luego mostraré algunas variaciones diferentes del problema.

Solución

La solución más simple es registrar explícitamente el tipo. Si ese tipo tiene un parámetro constructor primitivo, también dígale exactamente cómo crear el tipo.

Aquí hay un ejemplo. Digamos que tiene una clase llamada JsonLogger con el siguiente constructor:

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

Deberá registrar explícitamente este tipo y especificar cómo 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)

Encapsular los parámetros primitivos

Cuando tenga una combinación de parámetros primitivos que no se puedan resolver automáticamente y tipos que se puedan resolver, considere encapsular los parámetros primitivos en una clase. De lo contrario, cuando le diga cómo crear el objeto, tendrá que llamar repetidamente a IServiceProvider.GetService() para todos los tipos que se pueden resolver.

Aquí hay un ejemplo. Digamos que tiene el siguiente constructor:

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

Encapsule los dos parámetros primitivos:

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

Luego registre todos los tipos:

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)

Ejemplo de causa 1:services.AddSingleton()

Cuando estás registrando el tipo y diciéndole qué tipo concreto quieres, y ese tipo tiene un parámetro primitivo, como este:

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

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

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

Entonces obtendrás esta excepción:

Tienes que decirle cómo construir el tipo, ya que no sabe cómo resolver el parámetro constructor primitivo.

Ejemplo de causa 2:services.AddSingleton

Cuando intenta registrar el tipo sin decirle explícitamente a qué tipo concreto debe resolver, así:

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

		services.AddSingleton<ILogger>();
	}

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

Entonces obtendrá la siguiente excepción:

Ejemplo de causa 3:cuando no registra el tipo

Supongamos que tiene un controlador que depende de 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)

Si no registra el tipo del que depende (ILogger), obtendrá la siguiente excepción:

Nota:Esto no es Microsoft.Extensions.Logging.ILogger.