Home > Back-end >  .NET6: How to implement Dependency Injection from controller to service and from service to DbContex
.NET6: How to implement Dependency Injection from controller to service and from service to DbContex

Time:01-08

I'm trying to figure out Dependency Injection with .NET6. I have in my Visual Studio 2022 solution, one project having one controller. The controller constructor has an interface IWorkstationService, which I want to inject.

    public class WorkstationsController : ControllerBase
    {
        private IWorkstationService m_workstationService;

        public WorkstationsController(IWorkstationService workstationService)
        {
            m_workstationService = workstationService;
        }

In another project, I implemented the service which has a DbContext in its constructor which I want injected:

    public class WorkstationServiceImpl : IWorkstationService
    {
        private GCS156Context m_dbContext;

        public WorkstationServiceImpl(GCS156Context dbContext)
        {
            m_dbContext = dbContext;
        }

In my first project, I have the following in the Program.cs file:

    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddControllersWithViews();
    builder.Services.AddRazorPages();
    
    var connectionString = builder.Configuration.GetValue<string>("ConnectionStrings:Gcs156");
    builder.Services.AddSqlServer<GCS156Context>(connectionString);
    builder.Services.AddScoped<IWorkstationService, WorkstationServiceImpl>();
    var app = builder.Build();

The problem is that the first project (where I have my controller) is not compiling. I get the Exception below. But I don't know how to fix this. Should I register the DbContext in the DI Container in the first project too? I don't understand why I should. It's not being used in the first project, it is used in the second project, the service.

System.AggregateException
  HResult=0x80131500
  Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: BlazorApp1.Database.Service.IWorkstationService Lifetime: Scoped ImplementationType: BlazorApp1.Workstations.Service.WorkstationServiceImpl': Unable to resolve service for type 'BlazorApp1.Database.Service.Models.GCS156Context' while attempting to activate 'BlazorApp1.Workstations.Service.WorkstationServiceImpl'.)
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
   at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
   at Program.<Main>$(String[] args) in C:\Users\rayca\source\repos\BlazorApp1\BlazorApp1\Server\Program.cs:line 14

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: BlazorApp1.Database.Service.IWorkstationService Lifetime: Scoped ImplementationType: BlazorApp1.Workstations.Service.WorkstationServiceImpl': Unable to resolve service for type 'BlazorApp1.Database.Service.Models.GCS156Context' while attempting to activate 'BlazorApp1.Workstations.Service.WorkstationServiceImpl'.

Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'BlazorApp1.Database.Service.Models.GCS156Context' while attempting to activate 'BlazorApp1.Workstations.Service.WorkstationServiceImpl'.

CodePudding user response:

you have to use this syntax to add dbcontext, not AddSqlServer

builder.Services.AddDbContext<GCS156Context>(options => 
options.UseSqlServer(Configuration.GetConnectionString("Gcs156")));

CodePudding user response:

According to the docs for Blazor apps you need to use AddDbContextFactory since:

Some application types (e.g. ASP.NET Core Blazor) use dependency injection but do not create a service scope that aligns with the desired DbContext lifetime. Even where such an alignment does exist, the application may need to perform multiple units-of-work within this scope. For example, multiple units-of-work within a single HTTP request.

So you need to change builder.Services.AddSqlServer<GCS156Context>(connectionString); to something like:

builder.Services.AddDbContextFactory<GCS156Context>(
    options => options.UseSqlServer(connectionString));

ASP.NET Core Blazor Server with Entity Framework Core (EFCore)

  •  Tags:  
  • Related