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

C#Dependency Injectionasp.net Coreasp.net Core-Mvc

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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 - C#

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 - C#

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 - C#

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 - C#

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

Solution 6 - C#

You need to add a new service for DBcontext in the startup

Default

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

Add this

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

Solution 7 - C#

Public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IEventRepository, EventRepository>();           
}

You forgot to add "services.AddScoped" in startup ConfigureServices method.

Solution 8 - C#

In my case, .Net Core 3.0 API in Startup.cs, in method

public void ConfigureServices(IServiceCollection services)

I had to add

services.AddScoped<IStateService, StateService>();

Solution 9 - C#

I had to add this line in the ConfigureServices in order to work.

services.AddSingleton<IOrderService, OrderService>();

Solution 10 - C#

I got this issue because of a rather silly mistake. I had forgotten to hook my service configuration procedure to discover controllers automatically in the ASP.NET Core application.

Adding this method solved it:

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

Solution 11 - C#

I was getting below exception

        System.InvalidOperationException: Unable to resolve service for type 'System.Func`1[IBlogContext]' 
        while attempting to activate 'BlogContextFactory'.\r\n at 
        Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, ISet`1 callSiteChain)\r\n at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType, ServiceProvider serviceProvider)\r\n at System.Collections.Concurrent.ConcurrentDictionaryExtensions.GetOrAdd[TKey, TValue, TArg] (ConcurrentDictionary`2 dictionary, TKey key, Func`3 valueFactory, TArg arg)\r\n at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)\r\n at Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)\r\n at lambda_method(Closure , IServiceProvider , Object[] )\r\n at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)\r\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()

Because I wanted register Factory to create instances of DbContext Derived class IBlogContextFactory and use Create method to instantiate instance of Blog Context so that I can use below pattern along with dependency Injection and can also use mocking for unit testing.

the pattern I wanted to use is

public async Task<List<Blog>> GetBlogsAsync()
        {
            using (var context = new BloggingContext())
            {
                return await context.Blogs.ToListAsync();
            }
        }

But Instead of new BloggingContext() I want to Inject factory via constructor as in below BlogController class

    [Route("blogs/api/v1")]

public class BlogController : ControllerBase
{
    IBloggingContextFactory _bloggingContextFactory;

    public BlogController(IBloggingContextFactory bloggingContextFactory)
    {
        _bloggingContextFactory = bloggingContextFactory;
    }

    [HttpGet("blog/{id}")]
    public async Task<Blog> Get(int id)
    {
        //validation goes here 
        Blog blog = null;
        // Instantiage context only if needed and dispose immediately
        using (IBloggingContext context = _bloggingContextFactory.CreateContext())
        {
            blog = await context.Blogs.FindAsync(id);
        }
        //Do further processing without need of context.
        return blog;
    }
}

here is my service registration code

            services
            .AddDbContext<BloggingContext>()
            .AddTransient<IBloggingContext, BloggingContext>()
            .AddTransient<IBloggingContextFactory, BloggingContextFactory>();

and below are my models and factory classes

    public interface IBloggingContext : IDisposable
{
    DbSet<Blog> Blogs { get; set; }
    DbSet<Post> Posts { get; set; }
}

public class BloggingContext : DbContext, IBloggingContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseInMemoryDatabase("blogging.db");
        //optionsBuilder.UseSqlite("Data Source=blogging.db");
    }
}

public interface IBloggingContextFactory
{
    IBloggingContext CreateContext();
}

public class BloggingContextFactory : IBloggingContextFactory
{
    private Func<IBloggingContext> _contextCreator;
    public BloggingContextFactory(Func<IBloggingContext> contextCreator)// This is fine with .net and unity, this is treated as factory function, but creating problem in .netcore service provider
    {
        _contextCreator = contextCreator;
    }

    public IBloggingContext CreateContext()
    {
        return _contextCreator();
    }
}

public class Blog
{
    public Blog()
    {
        CreatedAt = DateTime.Now;
    }

    public Blog(int id, string url, string deletedBy) : this()
    {
        BlogId = id;
        Url = url;
        DeletedBy = deletedBy;
        if (!string.IsNullOrWhiteSpace(deletedBy))
        {
            DeletedAt = DateTime.Now;
        }
    }
    public int BlogId { get; set; }
    public string Url { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime? DeletedAt { get; set; }
    public string DeletedBy { get; set; }
    public ICollection<Post> Posts { get; set; }

    public override string ToString()
    {
        return $"id:{BlogId} , Url:{Url} , CreatedAt : {CreatedAt}, DeletedBy : {DeletedBy}, DeletedAt: {DeletedAt}";
    }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

----- To Fix this in .net Core MVC project -- I did below changes on dependency registration

            services
            .AddDbContext<BloggingContext>()
            .AddTransient<IBloggingContext, BloggingContext>()
            .AddTransient<IBloggingContextFactory, BloggingContextFactory>(
                    sp => new BloggingContextFactory( () => sp.GetService<IBloggingContext>())
                );

In short in .net core developer is responsible to inject factory function, which in case of Unity and .Net Framework was taken care of.

Solution 12 - C#

This issue is because you didn't register the data access component with the interface written for it. Try using as follows

services.AddTransient<IMyDataProvider, MyDataAccess>();`

Solution 13 - C#

For me it worked to add the DB context in the ConfigureServices as follows:

services.AddDBContext<DBContextVariable>();

Solution 14 - C#

If you are using AutoFac and getting this error, you should add an "As" statement to specify the service that the concrete implementation implements.

Ie. you should write:

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

instead of

containerBuilder.RegisterType<DataService>();

Solution 15 - C#

ohh, Thank @kimbaudi, i followed this tuts

https://dotnettutorials.net/lesson/generic-repository-pattern-csharp-mvc/

and got the same error as your. But after read your code i found out my solution was adding

> services.AddScoped(IGenericRepository, GenericRepository);

into ConfigureServices method in StartUp.cs file =))

Solution 16 - C#

I had the same issue and found out that my code was using the injection before it was initialized.

services.AddControllers(); // Will cause a problem if you use your IBloggerRepository in there since it's defined after this line.
services.AddScoped<IBloggerRepository, BloggerRepository>();

I know it has nothing to do with the question, but since I was sent to this page, I figure out it my be useful to someone else.

Solution 17 - C#

Resolving a service is done even before the class code is reached, so we need to check our dependency injections.

In my case I added

        services.AddScoped<IMeasurementService, MeasurementService>();

in StartupExtensions.cs

Solution 18 - C#

You might be missing this:

services.AddScoped<IDependencyTwoThatIsDependentOnDependencyOne, DependencyTwoThatIsDependentOnDependencyOne>();

Solution 19 - C#

I received this error message with ILogger being injected into a .NET 5 class. I needed to add the class type to fix it.

ILogger logger --> ILogger <MyClass> logger

Solution 20 - C#

I replaced

services.Add(new ServiceDescriptor(typeof(IMyLogger), typeof(MyLogger)));

With

services.AddTransient<IMyLogger, MyLogger>();

And it worked for me.

Solution 21 - C#

Add services.AddSingleton(); in your ConfigureServices method of Startup.cs file of your project.

public void ConfigureServices(IServiceCollection services)
	{
		services.AddRazorPages();
		// To register interface with its concrite type
		services.AddSingleton<IEmployee, EmployeesMockup>();
	}

For More details please visit this URL : https://www.youtube.com/watch?v=aMjiiWtfj2M

for All methods (i.e. AddSingleton vs AddScoped vs AddTransient) Please visit this URL: https://www.youtube.com/watch?v=v6Nr7Zman_Y&list=PL6n9fhu94yhVkdrusLaQsfERmL_Jh4XmU&index=44)

Solution 22 - C#

Change BloggerRepository to IBloggerRepository

Solution 23 - C#

I had problems trying to inject from my Program.cs file, by using the CreateDefaultBuilder like below, but ended up solving it by skipping the default binder. (see below).

var host = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.ConfigureServices(servicesCollection => { servicesCollection.AddSingleton<ITest>(x => new Test()); });
    webBuilder.UseStartup<Startup>();
}).Build();

It seems like the Build should have been done inside of ConfigureWebHostDefaults to get it work, since otherwise the configuration will be skipped, but correct me if I am wrong.

This approach worked fine:

var host = new WebHostBuilder()
.ConfigureServices(servicesCollection =>
{
    var serviceProvider = servicesCollection.BuildServiceProvider();
    IConfiguration configuration = (IConfiguration)serviceProvider.GetService(typeof(IConfiguration));
    servicesCollection.AddSingleton<ISendEmailHandler>(new SendEmailHandler(configuration));
})
.UseStartup<Startup>()
.Build();

This also shows how to inject an already predefined dependency in .net core (IConfiguration) from

Solution 24 - C#

If you are using dotnet 5 and versions below, you can also check whether you have register the repository in the services.

Solution 25 - C#

Had the same issue all I did was to register my DBContext in Startup.cs.

The problem is that you are calling a DBContext that the application has not registered with so it does not know what to do when your view tries to reference it.

Key part of the error message, "while attempting to activate"

 private readonly SmartPayDBContext _context;

Solution that worked for me

    public void ConfigureServices(IServiceCollection services)
    {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            
            services.AddDbContext<SmartPayDBContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
    }

Solution 26 - C#

Not sure if this will help anyone else, but I was correctly dependency injecting and got this error when trying to access my API controllers.

I had to shut down the project and rebuild after already adding them to my startup.cs class - for some reason a rebuild got Visual Studio to recognize the service class was properly registered when before it was getting an error.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkimbaudiView Question on Stackoverflow
Solution 1 - C#DavidGView Answer on Stackoverflow
Solution 2 - C#hsopView Answer on Stackoverflow
Solution 3 - C#riqitangView Answer on Stackoverflow
Solution 4 - C#Sibeesh VenuView Answer on Stackoverflow
Solution 5 - C#AdrianView Answer on Stackoverflow
Solution 6 - C#Warit TaveekarnView Answer on Stackoverflow
Solution 7 - C#Prakash CSView Answer on Stackoverflow
Solution 8 - C#Jitendra SawantView Answer on Stackoverflow
Solution 9 - C#MikeView Answer on Stackoverflow
Solution 10 - C#silkfireView Answer on Stackoverflow
Solution 11 - C#RajnikantView Answer on Stackoverflow
Solution 12 - C#Shailesh TiwariView Answer on Stackoverflow
Solution 13 - C#LuisView Answer on Stackoverflow
Solution 14 - C#tbfaView Answer on Stackoverflow
Solution 15 - C#SonView Answer on Stackoverflow
Solution 16 - C#SauleilView Answer on Stackoverflow
Solution 17 - C#Onat KorucuView Answer on Stackoverflow
Solution 18 - C#Jack JohnsView Answer on Stackoverflow
Solution 19 - C#CryptcView Answer on Stackoverflow
Solution 20 - C#satish madarapuView Answer on Stackoverflow
Solution 21 - C#Bhanu PratapView Answer on Stackoverflow
Solution 22 - C#Shah ZainView Answer on Stackoverflow
Solution 23 - C#SgeddaView Answer on Stackoverflow
Solution 24 - C#Alagbe Sunmbo AmosView Answer on Stackoverflow
Solution 25 - C#Akieno GayleView Answer on Stackoverflow
Solution 26 - C#Eric ConklinView Answer on Stackoverflow