Search code examples
c#dependency-injectionentity-framework-coreasp.net-core-mvc

How to solve Dependency Injection error in DbContext?


I used standard template ASP.NET Core MVC web app. And I've got this problem after adding DbContext:

InvalidOperationException: Unable to resolve service for type testing_ASP.Models.MyAppContext while attempting to activate testing_ASP.Controllers.HomeController. Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)

This is my Program.cs:

namespace testing_ASP
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
            builder.Services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(connectionString));
            builder.Services.AddDatabaseDeveloperPageExceptionFilter();

            builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseMigrationsEndPoint();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            app.MapRazorPages();

            app.Run();
        }
    }
}

This is MyAppContext:

using Microsoft.EntityFrameworkCore;

namespace testing_ASP.Models
{
    public class MyAppContext : DbContext
    {
        public DbSet<Company> Companies { get; set; } = null!;

        public MyAppContext(DbContextOptions<MyAppContext> options) : base(options) 
        {
            Database.EnsureCreated();
        }
    }
}

And this is HomeController.cs:

namespace testing_empty_ASP.Controllers
{
    public class HomeController : Controller
    {
        MyAppContext db;

        public HomeController(MyAppContext context)
        {
            db = context;
        }

    public ViewResult Index()
        {
                var company = new List<Company> {new Company(){PublicName = "McDonald's", Branch = "Restaurant" },
                                 new Company(){PublicName = "Etalon ltd", Branch = "Trading"},
                                 new Company(){PublicName = "Tele2", Branch = "Communication"}
                                };
                db.Companies.AddRange(company);
                db.SaveChanges();

            return View();
        }
    }
}

And this is the database connection string from appsettings.json:

"ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-testing_ASP-c67cc9e8-c350-434f-b384-17b29d00f79d;Trusted_Connection=True;MultipleActiveResultSets=true"
}

Solution

  • I see that you register ApplicationDbContext but not MyAppContext

    builder.Services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(connectionString));
    

    There should be also another line that registers it.

    builder.Services.AddDbContext<MyAppContext>(options =>
                    options.UseSqlServer(connectionString));