I have a minimal API project where I am using the MediatR v12.2.0. The code works fine when I debug using Visual Studio 2022, however, I am not able to get the code deployed to docker. In docker, once the app runs, I see the following messages in the logs.
2024-01-31 17:56:50 Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MediatR.IMediator Lifetime: Transient ImplementationType: MediatR.Mediator': A suitable constructor for type 'MediatR.Mediator' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.)
2024-01-31 17:56:50 ---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: MediatR.IMediator Lifetime: Transient ImplementationType: MediatR.Mediator': A suitable constructor for type 'MediatR.Mediator' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.
2024-01-31 17:56:50 ---> System.InvalidOperationException: A suitable constructor for type 'MediatR.Mediator' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache, ServiceIdentifier, Type , CallSiteChain)
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor, ServiceIdentifier, CallSiteChain, Int32)
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(ServiceDescriptor, CallSiteChain)
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceProvider.ValidateService(ServiceDescriptor)
2024-01-31 17:56:50 --- End of inner exception stack trace ---
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceProvider.ValidateService(ServiceDescriptor)
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection``1, ServiceProviderOptions)
2024-01-31 17:56:50 --- End of inner exception stack trace ---
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection``1, ServiceProviderOptions)
2024-01-31 17:56:50 at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection, ServiceProviderOptions)
2024-01-31 17:56:50 at Microsoft.Extensions.Hosting.HostApplicationBuilder.<>c__DisplayClass12_0.<.ctor>b__0()
2024-01-31 17:56:50 at Microsoft.Extensions.Hosting.HostApplicationBuilder.Build()
2024-01-31 17:56:50 at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
2024-01-31 17:56:50 at Program.<Main>$(String[]) in /app/apis/services/Pique.Services/Program.cs:line 119
2024-01-31 17:56:50 at Program.<Main>(String[])
I tried using the following two methods to register the MediatR in the IoC container.
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
builder.Services.AddMediatR(config => { config.RegisterServicesFromAssemblyContaining<Program>(); });
But I still keep seeing the same error message. Does that message mean that .NET is not able to resolve to a concrete instance of the IMediator? This did work back in .NET 6. I simply upgraded the .net version to 8 and upgraded the referenced libraries in Visual Studio and started seeing this when I deploy to docker.
Below is my program.cs file:
using Dapper.FluentMap;
using Microsoft.OpenApi.Models;
using Pique.Common.Exceptions;
using Pique.Services.Endpoints;
using Pique.Services.Handlers.DoloDocs;
using Pique.Services.Middleware;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// Register MediatR
//builder.Services.AddMediatR(config => {
// config.RegisterServicesFromAssembly(typeof(Pique.Services.AutoMapperProfile).Assembly);
//});
//builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly()));
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(typeof(Program).GetTypeInfo().Assembly));
// Register Automapper
builder.Services.AddAutoMapper(config =>
{
config.AddProfile<Pique.Services.AutoMapperProfile>();
});
var app = builder.Build();
app.UseCors();
// Add global exception handler
app.UseMiddleware<ExceptionMiddleware>();
// Add claims middleware - Used for Authentication & Authorization
app.UseMiddleware<ClaimsMiddleware>();
// Add request logging middleware
app.UseMiddleware<Pique.Common.RequestLoggerMiddleware>();
// Use Swagger UI to display the documentation
app.UseSwagger();
app.UseSwaggerUI(o =>
{
o.DefaultModelsExpandDepth(-1);
});
await app.RunAsync();
And here's my Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
EXPOSE 8080
# copy api project
COPY /apis/services/Services/ ./apis/services/Services/
# build out the solution
WORKDIR /app/apis/services/Services
RUN dotnet restore
RUN dotnet publish -c Release --self-contained true /p:PublishTrimmed=true -o /out
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
COPY --from=build-env /out .
ENTRYPOINT ["dotnet", "Services.dll"]