Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法从Microsoft.Extensions.Logging解析ILogger_C#_.net_Dependency Injection_.net Core_Ilogger - Fatal编程技术网

C# 无法从Microsoft.Extensions.Logging解析ILogger

C# 无法从Microsoft.Extensions.Logging解析ILogger,c#,.net,dependency-injection,.net-core,ilogger,C#,.net,Dependency Injection,.net Core,Ilogger,我已经这样配置了控制台应用程序的Main var services = new ServiceCollection() .AddLogging(logging => logging.AddConsole()) .BuildServiceProvider(); 然后我尝试在另一个类中使用它 private readonly ILogger _logger; public MyClass(ILogger log

我已经这样配置了控制台应用程序的
Main

var services = new ServiceCollection()
                .AddLogging(logging => logging.AddConsole())
                .BuildServiceProvider();
然后我尝试在另一个类中使用它

    private readonly ILogger _logger;

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

    public void MyFunc()
    {
        _logger.Log(LogLevel.Error, "My Message");
    }
System.InvalidOperationException:'无法解析类型的服务 'Microsoft.Extensions.Logging.ILogger'

我试过解决办法,但对我不起作用

编辑 根据雅科夫下面的评论,我能够通过这样做正确地解决它

    public MyClass(ILogger<MyClass> logger)
    {
        _logger = logger;
    }
公共MyClass(ILogger记录器)
{
_记录器=记录器;
}

我希望在最初的
BuildServiceProvider
中有此功能,但每次我想使用记录器(或创建自己的ILogger)时,我都必须重复此功能。

我假设您使用的是.net core web应用程序的默认模板。
在你的Startup.cs中,你应该有这样一个方法↓↓↓↓↓↓↓

// 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
        });

    }
//此方法由运行时调用。使用此方法向容器中添加服务。
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>true;
options.MinimumSameSitePolicy=SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//服务在这里注册吗?还有你想要的其他东西吗
services.AddLogging(配置=>
{
config.AddDebug();
config.AddConsole();
//等
});
}
编辑:我已经为你写了一个简单的程序来展示它是如何工作的

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>();
     }
}
公共类MyClass
{
专用只读ILogger\u记录器;
公共MyClass(ILogger记录器)
{
_记录器=记录器;
}
public void MyFunc()
{
_logger.Log(LogLevel.Error,“我的消息”);
}
}
公共课程
{
公共静态void Main(字符串[]args)
{
var services=newservicecolection().AddLogging(logging=>logging.AddConsole());
services.AddSingleton();//Singleton还是transient?!
var s=services.BuildServiceProvider();
var myclass=s.GetService();
}
}
编辑:程序的输出:
ILogger
在默认情况下不再注册,但已注册。如果仍要使用ILogger,可以通过以下方式(Startup.cs)手动注册它:

因此:

public void配置服务(IServiceCollection服务)
{
var serviceProvider=services.BuildServiceProvider();
var logger=serviceProvider.GetService();
服务。AddSingleton(类型(ILogger),记录器);
...
}

ILogger现在将通过.NET Core中的构造函数注入进行解析,
ILogger
将自动为您注册。由于
ILogger
继承自
ILogger
,您可以从
iSeries Provider
请求
ILogger
的实例

例如:
services.AddSingleton(svc=>svc.GetRequiredService())


请注意,只要有非泛型的
ILogger
构造函数参数,这将返回一个
ILogger
,因此如果需要多个构造函数参数,请使用
AddSingleton
(或瞬态/或作用域)专门为该实例创建它实现工厂覆盖。

我在尝试使用
ILogger
(因为它不再被注入)时使用的方法,例如注入
ILogger工厂
,然后当你的代码需要一个特定的记录器时(比如你正在创建的某个自定义工厂,
LoggerFactory.CreateLogger(“记录器名称”)
-如下

但对于您的情况,看起来您需要一个
ILogger


此答案不一定适用于.net Core或海报正在使用的任何依赖项注入。我在asp.net forms web应用程序中使用Autofac查找修复此错误的方法时遇到了此问题。日志记录未“默认注册”的答案导致我将此添加到我的注册中:

builder.RegisterType<LoggerFactory>().As<ILoggerFactory>().SingleInstance();
builder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>)).SingleInstance();
builder.RegisterType().As().SingleInstance();
RegisterGeneric(typeof(Logger)).As(typeof(ILogger)).SingleInstance();

现在它对我有效了。这是我第二次搜索这个答案,结果到了这里,我忘记了第一次是如何修复的。所以我想我应该发布我的答案。

正如一篇评论中所指出的,接受的答案有一个问题,
BuildServiceProvider
不应该在
ConfigureServices
中使用,因为它创建了每个单例的副本(事实上,是整个DI容器的副本)。这里有一个避免该问题的替代行。在
ConfigureServices
中,添加该行

services.AddSingleton<Microsoft.Extensions.Logging.ILogger>(provider => 
   provider.GetRequiredService<Microsoft.Extensions.Logging.ILogger<AnyClass>>());
services.AddSingleton(提供者=>
provider.GetRequiredService());
其中,
AnyClass
可以是任何类,如接受答案中所述。这会将
ILogger
的分辨率重定向到
ILogger
的分辨率

与公认的答案一样,这个选项的缺点是Serilog的
SourceContext
将设置为
AnyClass
。因此,如果Serilog配置包含
{SourceContext}的
outputTemplate
,您的日志将显示
AnyClass
,而不是包含日志语句的类。

基于@answer了解如何注册Microsoft.Extensions的通用日志提供程序。DependencyInjection

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

services.AddSingleton<ILoggerFactory, LoggerFactory>()
services.Add(ServiceDescriptor.Describe(typeof(ILogger<>),typeof(Logger<>),ServiceLifetime.Scoped))
var services=newservicecolection()
.AddLogging(logging=>logging.AddConsole())
.BuildServiceProvider();
services.AddSingleton()
services.Add(servicescriptor.description(typeof(ILogger)、typeof(Logger)、ServiceLifetime.Scoped))
<代码>,PAR在哪里?
public class MyClass
{

    private readonly ILoggerFactory _loggerFactory;


    public MyClass(ILoggerFactory loggerFactory)
    {
        _loggerFactory = _loggerFactory;
    }
    public void MyFunc()
    {
       new MyNewThatsASpecialCase(_loggerFactory.CreateLogger("MyNewThatsASpecialCase"));
    }
}
builder.RegisterType<LoggerFactory>().As<ILoggerFactory>().SingleInstance();
builder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>)).SingleInstance();
services.AddSingleton<Microsoft.Extensions.Logging.ILogger>(provider => 
   provider.GetRequiredService<Microsoft.Extensions.Logging.ILogger<AnyClass>>());
var services = new ServiceCollection()
                            .AddLogging(logging => logging.AddConsole())
                            .BuildServiceProvider();

services.AddSingleton<ILoggerFactory, LoggerFactory>()
services.Add(ServiceDescriptor.Describe(typeof(ILogger<>),typeof(Logger<>),ServiceLifetime.Scoped))