web-dev-qa-db-fra.com

Impossible de résoudre ILogger à partir de Microsoft.Extensions.Logging

J'ai configuré le Main de mon application console comme ceci

var services = new ServiceCollection()
                .AddLogging(logging => logging.AddConsole())
                .BuildServiceProvider();

Et puis j'essaye de l'utiliser dans une autre classe comme ça

    private readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public void MyFunc()
    {
        _logger.Log(LogLevel.Error, "My Message");
    }

System.InvalidOperationException: 'Impossible de résoudre le service pour le type' Microsoft.Extensions.Logging.ILogger '

J'ai essayé les solutions ici mais cela n'a pas fonctionné pour moi.

Modifier Basé sur le commentaire de Yaakov ci-dessous et ce commentaire Github Je peux le résoudre correctement en faisant ceci

    public MyClass(ILogger<MyClass> logger)
    {
        _logger = logger;
    }

J'aurais préféré avoir cela dans le BuildServiceProvider initial mais il semble que je vais devoir répéter cela chaque fois que je veux utiliser l'enregistreur (ou créer mon propre ILogger).

10
reggaemahn

ILogger n'est plus enregistré par défaut mais ILogger<T> est. Si vous souhaitez toujours utiliser ILogger, vous pouvez l'enregistrer manuellement avec les éléments suivants (Startup.cs):

    public void ConfigureServices(IServiceCollection services)
    {
        var serviceProvider = services.BuildServiceProvider();
        var logger = serviceProvider.GetService<ILogger<AnyClass>>();
        services.AddSingleton(typeof(ILogger), logger);
        ...
     }

Où AnyClass peut être quelque chose de générique, tel que:

     public class ApplicationLogs
     {
     }

Alors:

        public void ConfigureServices(IServiceCollection services)
        {
            var serviceProvider = services.BuildServiceProvider();
            var logger = serviceProvider.GetService<ILogger<ApplicationLog>>();
            services.AddSingleton(typeof(ILogger), logger);
            ...
         }

ILogger va maintenant résoudre via l'injection de constructeur

3
Sam Shiles

Je suppose que vous utilisez le modèle par défaut pour l'application Web de base .net.
Dans votre Startup.cs, vous devriez avoir une méthode comme celle-ci ↓↓↓↓↓↓↓

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });


        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        //Do the service register here and extra stuff you want
         services.AddLogging(config =>
        {
            config.AddDebug();
            config.AddConsole();
            //etc
        });

    }

Edit: j'ai écrit un programme simple pour vous montrer comment cela fonctionne

public class MyClass
{

    private readonly ILogger<MyClass> _logger;


    public MyClass(ILogger<MyClass> logger)
    {
        _logger = logger;
    }
    public void MyFunc()
    {
        _logger.Log(LogLevel.Error, "My Message");
    }
}



public class Program
{
    public static void Main(string[] args)
    {
        var services = new ServiceCollection().AddLogging(logging => logging.AddConsole());
        services.AddSingleton<MyClass>();//Singleton or transient?!
        var s = services.BuildServiceProvider();
        var myclass = s.GetService<MyClass>();
     }
}

enter image description here Edit: Sortie du programme: enter image description here

2