c# - Error de inyección de dependencia de núcleo de ASP.NET: no se puede resolver el servicio para el tipo al intentar activar




dependency-injection asp.net-core (10)

En mi caso, estaba tratando de hacer una inyección de dependencia para un objeto que requería argumentos de 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));

Creé una aplicación .NET Core MVC y uso el patrón de inyección de dependencia y 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'.

Modelo (Blog.cs)

namespace WebApplication1.Models
{
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
    }
}

DbContext (BloggingContext.cs)

using Microsoft.EntityFrameworkCore;
using WebApplication1.Models;

namespace WebApplication1.Data
{
    public class BloggingContext : DbContext
    {
        public BloggingContext(DbContextOptions<BloggingContext> options)
            : base(options)
        { }
        public DbSet<Blog> Blogs { get; set; }
    }
}

Repositorio (IBloggerRepository.cs y BloggerRepository.cs)

using System;
using System.Collections.Generic;
using WebApplication1.Models;

namespace WebApplication1.Data
{
    internal interface IBloggerRepository : IDisposable
    {
        IEnumerable<Blog> GetBlogs();

        void InsertBlog(Blog blog);

        void Save();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using WebApplication1.Models;

namespace WebApplication1.Data
{
    public class BloggerRepository : IBloggerRepository
    {
        private readonly BloggingContext _context;

        public BloggerRepository(BloggingContext context)
        {
            _context = context;
        }

        public IEnumerable<Blog> GetBlogs()
        {
            return _context.Blogs.ToList();
        }

        public void InsertBlog(Blog blog)
        {
            _context.Blogs.Add(blog);
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        private bool _disposed;

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}

Startup.cs (código relevante)

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<BloggingContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddScoped<IBloggerRepository, BloggerRepository>();

    services.AddMvc();

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

Controlador (BlogController.cs)

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using WebApplication1.Data;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
    public class BlogController : Controller
    {
        private readonly IBloggerRepository _repository;

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

        public IActionResult Index()
        {
            return View(_repository.GetBlogs().ToList());
        }

        public IActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Blog blog)
        {
            if (ModelState.IsValid)
            {
                _repository.InsertBlog(blog);
                _repository.Save();
                return RedirectToAction("Index");
            }
            return View(blog);
        }
    }
}

No estoy seguro de lo que estoy haciendo mal. ¿Algunas ideas?


Estaba teniendo un problema diferente, y sí, el constructor parametrizado para mi controlador o controlador ya estaba agregado con la interfaz correcta. Lo que hice fue algo sencillo. Simplemente voy a mi archivo startup.cs , donde pude ver una llamada para registrar el método.

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

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

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

Si ve, el parámetro para esta función es this IServiceCollection

Espero que esto ayude.


La excepción dice que no puede resolver el servicio para WebApplication1.Data.BloggerRepository porque el constructor en su controlador está pidiendo la clase concreta en lugar de la interfaz. Así que solo cambia eso:

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

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>();

Recibí este error porque declaró una variable (por encima del método ConfigureServices) de tipo que era mi contexto. Tuve:

CupcakeContext _ctx

No estoy seguro de lo que estaba pensando. Sé que es legal hacer esto si pasas un parámetro al método Configure.


Si está utilizando AutoFac y obtiene este error, debe agregar una instrucción "As" para especificar el servicio que implementa la implementación concreta.

Es decir. Deberías escribir:

containerBuilder.RegisterType<DataService>().As<DataService>();

en vez de

containerBuilder.RegisterType<DataService>();

Tengo este problema debido a un error bastante tonto. Había olvidado conectar mi procedimiento de configuración de servicio para descubrir controladores automáticamente en la aplicación ASP.NET Core.

Agregar este método lo resolvió:

// Add framework services.
            services.AddMvc()
                    .AddControllersAsServices();      // <---- Super important

Tuve que agregar esta línea en ConfigureServices para poder trabajar.

services.AddSingleton<IOrderService, OrderService>();

DBcontext agregar un nuevo servicio para DBcontext en el inicio

Defecto

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

Agrega esto

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

services.Add(new ServiceDescriptor(typeof(IMyLogger), typeof(MyLogger))) Con services.AddTransient<IMyLogger, MyLogger>()

Y funcionó para mí.





asp.net-core-mvc