Cannot resolve scoped service from root provider in ASP.NET Core 6 [duplicate]
Asked Answered
C

1

15

I'm coding a website with ASP.NET Core 6. It's originally a tutorial from YouTube with .NET Core 3. So I'm facing migration issues. Here, I have a DbInitializer file which contains all my data (i.e.: my database).

using DrinkAndGo.Data.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;

namespace DrinkAndGo.Data
{
public class DbInitializer
{
    public static void Seed(IApplicationBuilder applicationBuilder)
    {
        AppDbContext context =
            applicationBuilder.ApplicationServices.GetRequiredService<AppDbContext>();

        if (!context.Categories.Any())
        {
            context.Categories.AddRange(Categories.Select(c => c.Value));
        }

        if (!context.Drinks.Any())
        {
            context.AddRange
            (
                new Drink
                {
                    Name = "Beer",
                    Price = 7.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/beerL_2.jpg",
                    InStock = true,
                    IsPreferredDrink = true,
                    ImageThumbnailUrl = "http://imgh.us/beerS_1.jpeg"
                },
                new Drink
                {
                    Name = "Rum & Coke",
                    Price = 12.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/rumCokeL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/rumAndCokeS.jpg"
                },
                new Drink
                {
                    Name = "Tequila ",
                    Price = 12.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/tequilaL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/tequilaS.jpg"
                },
                new Drink
                {
                    Name = "Wine ",
                    Price = 16.75M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/wineL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/wineS.jpg"
                },
                new Drink
                {
                    Name = "Margarita",
                    Price = 17.95M,
                   
                    ImageUrl = "http://imgh.us/margaritaL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/margaritaS.jpg"
                },
                new Drink
                {
                    Name = "Whiskey with Ice",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/whiskyIceL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/whiskeyS.jpg"
                },
                new Drink
                {
                    Name = "Jägermeister",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/jagermeisterL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/jagermeisterS.jpg"
                },
                new Drink
                {
                    Name = "Champagne",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/champagneL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/champagneS.jpg"
                },
                new Drink
                {
                    Name = "Piña colada ",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/pinaColadaL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/pinaColadaS.jpg"
                },
                new Drink
                {
                    Name = "White Russian",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/whiteRussianL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/whiteRussianS.jpg"
                },
                new Drink
                {
                    Name = "Long Island Iced Tea",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/longTeaL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/islandTeaS.jpg"
                },
                new Drink
                {
                    Name = "Vodka",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/vodkaL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/vodkaS.jpg"
                },
                new Drink
                {
                    Name = "Gin and tonic",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/ginTonicL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/ginTonicS.jpg"
                },
                new Drink
                {
                    Name = "Cosmopolitan",
                    Price = 15.95M,
                    
                    Category = Categories["Alcoholic"],
                    ImageUrl = "http://imgh.us/cosmopolitanL.jpg",
                    InStock = false,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/cosmopolitanS.jpg"
                },
                new Drink
                {
                    Name = "Tea ",
                    Price = 12.95M,
                    
                    Category = Categories["Non-alcoholic"],
                    ImageUrl = "http://imgh.us/teaL.jpg",
                    InStock = true,
                    IsPreferredDrink = true,
                    ImageThumbnailUrl = "http://imgh.us/teaS.jpg"
                },
                new Drink
                {
                    Name = "Water ",
                    Price = 12.95M,
                    
                    Category = Categories["Non-alcoholic"],
                    ImageUrl = "http://imgh.us/waterL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/waterS_1.jpg"
                },
                new Drink
                {
                    Name = "Coffee ",
                    Price = 12.95M,
                    
                    Category = Categories["Non-alcoholic"],
                    ImageUrl = "http://imgh.us/coffeeL.jpg",
                    InStock = true,
                    IsPreferredDrink = true,
                    ImageThumbnailUrl = "http://imgh.us/coffeS.jpg"
                },
                new Drink
                {
                    Name = "Kvass",
                    Price = 12.95M,
                    
                    Category = Categories["Non-alcoholic"],
                    ImageUrl = "http://imgh.us/kvassL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/kvassS.jpg"
                },
                new Drink
                {
                    Name = "Juice ",
                    Price = 12.95M,
                    
                    Category = Categories["Non-alcoholic"],
                    ImageUrl = "http://imgh.us/juiceL.jpg",
                    InStock = true,
                    IsPreferredDrink = false,
                    ImageThumbnailUrl = "http://imgh.us/juiceS.jpg"
                }
            );
        }

        context.SaveChanges();
    }

    private static Dictionary<string, Category> categories;
    public static Dictionary<string, Category> Categories
    {
        get
        {
            if (categories == null)
            {
                var genresList = new Category[]
                {
                    new Category { CategoryName = "Alcoholic", Description="All alcoholic drinks" },
                    new Category { CategoryName = "Non-alcoholic", Description="All non-alcoholic drinks" }
                };

                categories = new Dictionary<string, Category>();

                foreach (Category genre in genresList)
                {
                    categories.Add(genre.CategoryName, genre);
                }
            }

            return categories;
        }
    }
}
}

Then my Program.cs file:

using DrinkAndGo.Data;
using DrinkAndGo.Data.Interfaces;
using DrinkAndGo.Data.Mocks;
using DrinkAndGo.Data.Repositories;
using Microsoft.EntityFrameworkCore;
using static System.Net.Mime.MediaTypeNames;

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureServices(services =>
{
    services.AddTransient<IDrinkRepository, DrinkRepository>(); 
    services.AddTransient<ICategoryRepository, CategoryRepository>();
    services.AddScoped<AppDbContext>();

});

builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(
    builder.Configuration.GetConnectionString("DefaultConnection")
    ));

var app = builder.Build();


if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

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


app.Run();

When I run the app, with IIS Express, Visual Studio throws the following exception:

System.InvalidOperationException : 'Cannot resolve scoped service 'DrinkAndGo.Data.AppDbContext' from root provider.'

Could someone explain me the problem and how to solve it?

Compressive answered 31/5, 2022 at 11:59 Comment(0)
R
42

You need to create a scope to resolve Scoped services. Use ServiceProviderServiceExtensions.CreateScope:

public static void Seed(WebApplication app)
{
     using var scope = app.Services.CreateScope();
     AppDbContext context = scope.ServiceProvider.GetRequiredService<AppDbContext>();

    // use context
}
Romeo answered 31/5, 2022 at 12:4 Comment(4)
just note if you use the using in the constructor it will destroy it before you can use it in your methods.Moisture
As B.Ramburn said, you should not use the 'using' while creating the scope. Otherwise you should get an exception like this: System.ObjectDisposedException: Cannot access a disposed context instance.Annoyance
@Annoyance it depends on the use case. The provided method signature and implementation does not imply using the context outside the Seed method so using is just fine there. I would say that even more - you should use using unless the ownership of it is transferred, then you should transfer ownership of the scope itselfRomeo
This worked for me when adding a DI for a Quartz job, thanks!Aphasic

© 2022 - 2024 — McMap. All rights reserved.