CANNOT consume scoped from singlleton service

Nandini S 20 Reputation points
2024-02-12T09:39:44.1566667+00:00

After adding identitiy user to authentication and authorization part of user to Single service AppRepository without interface , facing exception error when the application start. how to debug this error and how to perform authentication

Developer technologies | ASP.NET | ASP.NET Core
{count} votes

1 answer

Sort by: Most helpful
  1. Anonymous
    2024-02-13T02:17:40.74+00:00

    Hi @Nandini S,

    CANNOT consume scoped from singlleton service

    From your description, I'm assuming you want to use the DbContext or UserManager in a Singleton service, right?

    By default. in asp.net core identity, the DbContext and UserManager instance are typically scoped to the lifetime of a request. If we access the Scoped service from a Singleton service, it will show the "CANNOT consume scoped from singlleton service" error.

    To solve this issue, in the Singleton service, we can access them via the IServiceProvider or IServiceScopeFactory, refer to the following sample code:

    TestSingletonService.cs:

    using Microsoft.AspNetCore.Identity;
    using WebApplication1.Data;
    
    namespace WebApplication1.Services
    {
        public interface ITestSingletonService
        {
            IdentityUser GetUserViaProvider();
            IdentityUser GetUserViaScopeFactory();
            IdentityUser GetUserViaUserManager();
        }
        public class TestSingletonService:ITestSingletonService
        {
            private readonly IHttpContextAccessor _httpContextAccessor;  //inject the httpcontext to get the current login user.
            private readonly IServiceProvider _serviceProvider;          //get the dbcontext via the IServiceProvider.
            private readonly IServiceScopeFactory _serviceScopeFactory;   //get the dbcontext via the IServiceScoptFactory.
             
            public TestSingletonService(IHttpContextAccessor httpContextAccessor,
                IServiceProvider serviceProvider, 
                IServiceScopeFactory serviceScopeFactory)
            {
                _httpContextAccessor = httpContextAccessor;
                _serviceProvider = serviceProvider;
                _serviceScopeFactory = serviceScopeFactory; 
            }
    
            public IdentityUser GetUserViaProvider()
            {
                using (var scope = _serviceProvider.CreateScope())
                {
                    var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                    // Use dbContext here
    
                    return dbContext.Users.Where(c => c.UserName == _httpContextAccessor.HttpContext.User.Identity.Name).FirstOrDefault();
                }
            }
            public IdentityUser GetUserViaScopeFactory()
            {
                using (var scope = _serviceScopeFactory.CreateScope())
                {
                    var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); 
                    // Use dbContext here
    
                    return dbContext.Users.Where(c => c.UserName == _httpContextAccessor.HttpContext.User.Identity.Name).FirstOrDefault();
                }
            }
    
            public IdentityUser GetUserViaUserManager()
            {
                using (var scope = _serviceScopeFactory.CreateScope())
                {
                    var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
                    var user = userManager.FindByNameAsync(_httpContextAccessor.HttpContext.User.Identity.Name).Result;
                    return user;
                }  
            }
        }
    }
    
    

    Then, in the Program.cs file, register the service:

    // 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();
    
    builder.Services.AddHttpContextAccessor();
    builder.Services.AddSingleton<ITestSingletonService, TestSingletonService>();
    
    

    In the MVC controller, we can access the singleton service like this:

        public class HomeController : Controller
        {
            private readonly ILogger<HomeController> _logger;
            private readonly ITestSingletonService _singletonservice;
            public HomeController(ILogger<HomeController> logger, ITestSingletonService testSingletonService)
            {
                _logger = logger;
                _singletonservice= testSingletonService;
            }
            public IActionResult Privacy()
            {
                var user1 = _singletonservice.GetUserViaProvider();
                var user2 = _singletonservice.GetUserViaScopeFactory();
                var user3 = _singletonservice.GetUserViaUserManager();
    
                return View();
            }
    
    

    The result as below: User's image

    If I misunderstand, please share your code to reproduce the problem.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
    Best regards,
    Dillion

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.