Jimminybob
Jimminybob

Reputation: 83

Unable to resolve service for type Microsoft.Extensions.Logging.ILogger

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.ILogger1[TransactionBehavior2[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.ILogger1[TransactionBehavior2[SubmitItemCommand,SubmitItemCommandResponse]]' for service type 'Microsoft.Extensions.Logging.ILogger1[TransactionBehavior2[SubmitItemCommand,SubmitItemCommandResponse]]'

.

Upvotes: 0

Views: 5281

Answers (2)

TomEberhard
TomEberhard

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

Jimminybob
Jimminybob

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

Related Questions