ASP.NET Core Dependency Injection error: Unable to resolve service for type while attempting to activate

581,525

Solution 1

To break down the error message:

Unable to resolve service for type 'WebApplication1.Data.BloggerRepository' while attempting to activate 'WebApplication1.Controllers.BlogController'.

That is saying that your application is trying to create an instance of BlogController but it doesn't know how to create an instance of BloggerRepository to pass into the constructor.

Now look at your startup:

services.AddScoped<IBloggerRepository, BloggerRepository>();

That is saying whenever a IBloggerRepository is required, create a BloggerRepository and pass that in.

However, your controller class is asking for the concrete class BloggerRepository and the dependency injection container doesn't know what to do when asked for that directly.

I'm guessing you just made a typo, but a fairly common one. So the simple fix is to change your controller to accept something that the DI container does know how to process, in this case, the interface:

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

Note that some objects have their own custom ways to be registered, this is more common when you use external Nuget packages, so it pays to read the documentation for them. For example if you got a message saying:

Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' ...

Then you would fix that using the custom extension method provided by that library which would be:

services.AddHttpContextAccessor();

For other packages - always read the docs.

Solution 2

I ran into this issue because in the dependency injection setup I was missing a dependency of a repository that is a dependency of a controller:

services.AddScoped<IDependencyOne, DependencyOne>();    <-- I was missing this line!
services.AddScoped<IDependencyTwoThatIsDependentOnDependencyOne, DependencyTwoThatIsDependentOnDependencyOne>();

Solution 3

In my case I was trying to do dependency injection for an object which required constructor arguments. In this case, during Startup I just provided the arguments from the configuration file, for example:

var config = Configuration.GetSection("subservice").Get<SubServiceConfig>();
services.AddScoped<ISubService>(provider => new SubService(config.value1, config.value2));

Solution 4

I was having a different problem, and yeah the parameterized constructor for my controller was already added with the correct interface. What I did was something straightforward. I just go to my startup.cs file, where I could see a call to register method.

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

In my case, this Register method was in a separate class Injector. So I had to add my newly introduced Interfaces there.

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

If you see, the parameter to this function is this IServiceCollection

Hope this helps.

Solution 5

Only if anyone have the same situation like me, I am doing a tutorial of EntityFramework with existing database, but when the new database context is created on the models folders, we need to update the context in the startup, but not only in services.AddDbContext but AddIdentity too if you have users authentication

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

services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<NewDBContext>()
                .AddDefaultTokenProviders();
Share:
581,525
kimbaudi
Author by

kimbaudi

website: https://paulkode.com game: https://bustazoo.com Bust A Zoo

Updated on July 08, 2022

Comments

  • kimbaudi
    kimbaudi almost 2 years

    I created an .NET Core MVC application and use Dependency Injection and Repository Pattern to inject a repository to my controller. However, I am getting an error:

    InvalidOperationException: Unable to resolve service for type 'WebApplication1.Data.BloggerRepository' while attempting to activate 'WebApplication1.Controllers.BlogController'.

    Model (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; }
        }
    }
    

    Repository (IBloggerRepository.cs & 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 (relevant code)

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

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

    I'm not sure what I'm doing wrong. Any ideas?

  • RaSor
    RaSor over 5 years
  • jleach
    jleach over 4 years
    Amazing how easy it is to overlook a single character... thanks!
  • m.t.bennett
    m.t.bennett about 4 years
    What a champion, recieved this while using HttpContextAccessor class, turns out I needed the IHttpContextAccessor
  • NoloMokgosi
    NoloMokgosi about 4 years
    So irritated because I waisted more than 30 minutes on this.Worst VS on Mac gives you "donet quit unexpectedly" error. Has to run on terminal to get the correct error, then I bumped into this solution.
  • user2982195
    user2982195 about 4 years
    Solved my problem, because I recognized my services were not in the correct "namespace".
  • Omzig
    Omzig almost 4 years
    This is the one i forgot to add. I missed the Injector reference to the service. Needed to .AddTransient<>(); Thank you guys!
  • theITvideos
    theITvideos over 3 years
    hey mate! that did it for me. I knew in my case it was this fix.
  • Kurtis Jungersen
    Kurtis Jungersen over 3 years
    Similarly, I was inadvertently activating the wrong object in Startup.cs. I had services.AddTransient<FooService, FooService>(); instead of services.AddTransient<IFooService, FooService>();. Those pesky letters LOL. Thanks for pointing me in the right direction!
  • Porter Lyman
    Porter Lyman about 3 years
    Brilliant. My issue was completely forgetting to register a new method in startup.cs. Though in my case, services.AddScoped instead of services.AddTransient.
  • Usama Aziz
    Usama Aziz almost 3 years
    Worked for me after a little tweak. If someone has already configured ConnectionString in DbContext, then you don't need to pass options => options.UseSqlServer( Configuration.GetConnectionString("NewConnection")). Just services.AddDbContext<NewDBContext>() will work.
  • JamesMatson
    JamesMatson almost 3 years
    I just came here to say that DavidG, your answer explains things so, so, so well. I really appreciated reading this and I just wanted to let you know!
  • vbguyny
    vbguyny almost 3 years
    My issue was that I needed to look at the arguments of the constructors for the classes that I was injecting. Once I added the types for the arguments the error disappeared!
  • nightingale2k1
    nightingale2k1 over 2 years
    jeeezzz... i just found this typo mistake. I was deleting "I" char by accident.
  • Dung
    Dung over 2 years
    @DavidG - You made my day sir! In my case I forgot to register the class in startup.cs and got the exact type of error. Thank you!
  • Jano du Toit
    Jano du Toit over 2 years
    Saved me in 2021 as well! Awesome answer from @DavidG!
  • DavidG
    DavidG over 2 years
    How does this add to the existing answers?
  • Anup Shah
    Anup Shah about 2 years
    The catchy phrase from the answer above... "That is saying whenever a IBloggerRepository is required, create a BloggerRepository and pass that in"
  • Sold Out
    Sold Out about 2 years
    This is rather a comment, then an answer.
  • SE7A.
    SE7A. almost 2 years
    Great !! thank you for saving my time <3
  • Lakshmana Kumar
    Lakshmana Kumar almost 2 years
    builder.Services.AddDbContext<DbContext>(); will work if you followed DB first approach and already created DBContext and Models in .NET6.