Reputation: 83
I am building a standalone application that hooks into another project to submit items that are ultimately inserted into a database (there are a number of event handlers included but I don't call these directly, they are referenced by the command that I call). When I am calling the command in question via MediatR I am getting the following error:
Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger
1[TransactionBehavior
2[SubmitItemCommand,SubmitItemCommandResponse]]' while attempting to activate 'TransactionBehavior`2[SubmitItemCommand,SubmitItemCommandResponse]'.
I have a start up class in my application that looks like this:
public ServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMediatR(typeof(Startup));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));
...
return services.BuildServiceProvider();
}
and the command in question is below:
public class TransactionBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : Command<TResponse>
{
private readonly ILogger<TransactionBehavior<TRequest, TResponse>> _logger;
public TransactionBehavior(ILogger<TransactionBehavior<TRequest, TResponse>> logger)
{
_logger = logger ?? throw new ArgumentException(nameof(logger));
}
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
try
{
...
}
catch (Exception ex)
{
_logger.LogError(ex, "Error handling transaction for {CommandName} ({@Command})", request.GetType().Name, request);
throw;
}
}
}
I've tried a number of solutions including adding an item to the services config for ILogger, however when I do that I get the error of:
Cannot instantiate implementation type 'Microsoft.Extensions.Logging.ILogger
1[TransactionBehavior
2[SubmitItemCommand,SubmitItemCommandResponse]]' for service type 'Microsoft.Extensions.Logging.ILogger1[TransactionBehavior
2[SubmitItemCommand,SubmitItemCommandResponse]]'
.
Upvotes: 0
Views: 5281
Reputation: 1091
For .NET 8, and building on Jimminybob's answer: if you do want to use Logger<SomeClass>
, add the two lines in Program.cs as explained above,
var builder = WebApplication.CreateBuilder(args)
...
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
...
var app = builder.Build();
and update the constructors of your controllers/services/repositories:
using Microsoft.Extensions.Logging;
public AuthController(
IConfiguration configuration,
ILogger<AuthController> logger,
ILoggerFactory loggerFactory,
IActionContextAccessor actionContext)
{
_logger = logger;
someRepository = new SomeRepository(arg1, new Logger<SomeRepository>(loggerFactory));
someService = new SomeService(arg1, someRepository, new Logger<SomeService>(loggerFactory));
etc;
}
then in the declaration of SomeRepository and SomeService:
public class SomeRepository : ISomeRepository
{
private readonly ILogger _logger;
public SomeRepository(string arg1, ILogger<SomeRepository> logger)
{
_logger = logger;
etc...
}
}
The exact error message that was being generated: System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: SomeNamespace.Server.Services.IAuthService Lifetime: Scoped ImplementationType: SomeNamespace.Server.Services.AuthService': Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'SomeNamespace.Server.Services.AuthService'.)'
Upvotes: 1
Reputation: 83
Just in case anyone else has a similar error, I was able to fix this by adding
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
to my startup.cs.
I thought I had to add in an ILogger referencing the particular class, which was generating the second error, but just adding in a generic version sorted everything out.
Upvotes: 4