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)
