Error de inyección de dependencia: no se puede resolver el servicio para el tipo al intentar activarlo, mientras la clase está registrada

Resuelto kimbaudi asked hace 8 años • 25 respuestas

Creé una aplicación .NET Core MVC y utilicé la inyección de dependencia y el patrón de repositorio para inyectar un repositorio en mi controlador. Sin embargo, recibo un error:

InvalidOperationException: no se puede resolver el servicio para el tipo 'WebApplication1.Data.BloggerRepository' al intentar activar 'WebApplication1.Controllers.BlogController'.

Repositorio:

public interface IBloggerRepository { ... }

public class BloggerRepository : IBloggerRepository { ... }

Controlador:

public class BlogController : Controller
{
    private readonly IBloggerRepository _repository;

    public BlogController(BloggerRepository repository)
    {
        _repository = repository;
    }

    public IActionResult Index() { ... }
}

Inicio.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    
    services.AddScoped<IBloggerRepository, BloggerRepository>();
}

No estoy seguro de qué estoy haciendo mal. ¿Algunas ideas?

kimbaudi avatar Dec 01 '16 06:12 kimbaudi
Aceptado

Para desglosar el mensaje de error:

No se puede resolver el servicio para el tipo 'WebApplication1.Data.BloggerRepository' al intentar activar 'WebApplication1.Controllers.BlogController'.

Es decir, su aplicación está intentando crear una instancia de BlogControllerpero no sabe cómo crear una instancia BloggerRepositorypara pasarla al constructor.

Ahora mira tu startup:

services.AddScoped<IBloggerRepository, BloggerRepository>();

Es decir, siempre que IBloggerRepositoryse requiera a, cree a BloggerRepositoryy páselo.

Sin embargo, su clase de controlador solicita la clase concreta BloggerRepositoryy el contenedor de inyección de dependencia no sabe qué hacer cuando se le solicita directamente.

Supongo que acabas de cometer un error tipográfico, pero es bastante común. Entonces, la solución simple es cambiar su controlador para aceptar algo que el contenedor DI sepa cómo procesar, en este caso, la interfaz:

public BlogController(IBloggerRepository repository)
//                    ^
//                    Add this!
{
    _repository = repository;
}

Tenga en cuenta que algunos objetos tienen sus propias formas personalizadas de registrarse; esto es más común cuando usa paquetes Nuget externos, por lo que vale la pena leer la documentación correspondiente. Por ejemplo, si recibe un mensaje que dice:

No se puede resolver el servicio para el tipo 'Microsoft.AspNetCore.Http.IHttpContextAccessor'...

Luego, lo solucionarías utilizando el método de extensión personalizado proporcionado por esa biblioteca, que sería:

services.AddHttpContextAccessor();

Para otros paquetes, lea siempre los documentos.

DavidG avatar Dec 01 '2016 00:12 DavidG

Me encontré con este problema porque en la configuración de inyección de dependencia me faltaba una dependencia de un repositorio que es una dependencia de un controlador:

services.AddScoped<IDependencyOne, DependencyOne>();    <-- I was missing this line!
services.AddScoped<IDependencyTwoThatIsDependentOnDependencyOne, DependencyTwoThatIsDependentOnDependencyOne>();
hsop avatar Aug 27 '2018 21:08 hsop

En mi caso, estaba intentando realizar una inyección de dependencia para un objeto que requería argumentos del constructor. En este caso, durante el inicio solo proporcioné los argumentos del archivo de configuración, por ejemplo:

var config = Configuration.GetSection("subservice").Get<SubServiceConfig>();
services.AddScoped<ISubService>(provider => new SubService(config.value1, config.value2));
riqitang avatar Jun 27 '2017 16:06 riqitang

Estaba teniendo un problema diferente y sí, el constructor parametrizado para mi controlador ya se agregó con la interfaz correcta. Lo que hice fue algo sencillo. Simplemente voy a mi startup.csarchivo, donde pude ver una llamada al método de registro.

public void ConfigureServices(IServiceCollection services)
{
   services.Register();
}

En mi caso, este Registermétodo estaba en una clase separada Injector. Así que tuve que agregar allí mis interfaces recién introducidas.

public static class Injector
{
    public static void Register(this IServiceCollection services)
    {
        services.AddTransient<IUserService, UserService>();
        services.AddTransient<IUserDataService, UserDataService>();
    }
}

Si ve, el parámetro de esta función esthis IServiceCollection

Espero que esto ayude.

Sibeesh Venu avatar Apr 06 '2018 05:04 Sibeesh Venu

Solo si alguien tiene la misma situación que yo, estoy haciendo un tutorial de EntityFramework con una base de datos existente, pero cuando se crea el nuevo contexto de la base de datos en las carpetas de modelos, necesitamos actualizar el contexto en el inicio, pero no solo en los servicios. AddDbContext pero AddIdentity también si tiene autenticación de usuarios

services.AddDbContext<NewDBContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<NewDBContext>()
                .AddDefaultTokenProviders();
Adrian avatar Apr 28 '2017 13:04 Adrian