Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.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# 将Asp.NETCore2注入用于多个项目的Serilog_C#_Asp.net_Logging_Asp.net Core Mvc_Serilog - Fatal编程技术网

C# 将Asp.NETCore2注入用于多个项目的Serilog

C# 将Asp.NETCore2注入用于多个项目的Serilog,c#,asp.net,logging,asp.net-core-mvc,serilog,C#,Asp.net,Logging,Asp.net Core Mvc,Serilog,我为Asp.Net Core 2.0配置了Serilog,它通过启动web项目中的.Net Core依赖项注入(如果我通过Microsoft.Extensions.Logging使用它)工作得很好,但我无法从任何其他项目访问它 以下是我所拥有的: Program.cs using System; using System.IO; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Exte

我为Asp.Net Core 2.0配置了Serilog,它通过启动web项目中的.Net Core依赖项注入(如果我通过Microsoft.Extensions.Logging使用它)工作得很好,但我无法从任何其他项目访问它

以下是我所拥有的:

Program.cs

using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;

namespace ObApp.Web.Mvc
{
    public class Program
    {
        public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
            .Build();

        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .CreateLogger();

            try
            {
                Log.Warning("Starting BuildWebHost");

                BuildWebHost(args).Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseSerilog()
                .Build();
    }
}
我得到了什么-网络(创业)项目

如果使用Microsoft.Extensions.Logging包装器,则注入在HomeController中工作:

using Microsoft.Extensions.Logging;

public class HomeController : Controller
{
    ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
        _logger.LogDebug("Controller instantiated.");
    }
}
InvalidOperationException:无法解析服务 尝试激活时输入'Serilog.ILogger' 'ObApp2.Web.Mvc.Controllers.HomeController'

我的大问题-其他项目

using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;

namespace ObApp.Web.Mvc
{
    public class Program
    {
        public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
            .Build();

        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .CreateLogger();

            try
            {
                Log.Warning("Starting BuildWebHost");

                BuildWebHost(args).Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseSerilog()
                .Build();
    }
}
我更大的问题是,如果我在解决方案中的另一个项目中工作,我无法通过我尝试过的任何方法通过DI获得记录器

当我尝试使用Microsoft.Extensions.Logging或Serilog进行注入时,在生成时会出现缺少参数的异常

using Microsoft.Extensions.Logging;
namespace ObApp.Domain
{
    public class MyTestClass(ILogger<MyTestClass> logger) { ... }

- or -

using Serilog;
namespace ObApp.Domain
{
    public class MyTestClass(ILogger logger) { ... }
使用Microsoft.Extensions.Logging;
命名空间ObApp.Domain
{
公共类MyTestClass(ILogger记录器){…}
-或-
使用Serilog;
命名空间ObApp.Domain
{
公共类MyTestClass(ILogger记录器){…}
两者都会生成生成错误,类似于:

没有给出与所需的形式化参数相对应的参数 “MyTestClass.MyTestClass(ILogger)”的参数“logger”

问题

using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;

namespace ObApp.Web.Mvc
{
    public class Program
    {
        public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
            .Build();

        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .CreateLogger();

            try
            {
                Log.Warning("Starting BuildWebHost");

                BuildWebHost(args).Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseSerilog()
                .Build();
    }
}
  • 使用这种类型的Serilog配置进行注入时,是否建议我在进行注入的类文件中引用Microsoft.Extensions.Logging或Serilog

  • 如何让DI完成所有项目


  • 有一种方法对我有效:

    我在ConfigureServices方法中使用AddSingleton()方法添加了Serilog.Core.Logger的实例。这解决了DI问题。此步骤取代了在启动构造函数中将Logger实例分配给Log.Logger的步骤

    services.AddSingleton((ILogger)new LoggerConfiguration()
                .MinimumLevel.Information()
                .WriteTo.File(<...>)
                .CreateLogger());
    
    services.AddSingleton((ILogger)new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.File()文件
    .CreateLogger());
    

    还要更改类文件中的引用以指向Serilog.Ilogger

    此解决方案正确地将记录器注入到外部项目或库中的类中

    我也尝试了Rufus建议的答案。我没有OP描述的问题,但我有一个更奇怪的问题:在
    ILogger
    被注入外部项目后,MS SQL的日志记录停止了工作。控制台日志记录工作。由于Serilog主要是一个静态服务,我意识到我应该将
    Log.Logger
    视为工厂。好处是您仍然可以自定义
    ILogger
    引用(例如,在构造函数中添加
    ForContext
    ),而不会影响“singleton”服务

    我已经发布了一个完整的工作解决方案,包括一个设置DI的控制台程序(在ASP.NET Core中也可以使用),一个包含Serilog getting started by zero demo的外部库,以及另一个作为服务管理Serilog的库

    重要的部分,Serilog服务注册,看起来是这样的(作为奖励,我们将
    ProcessExit
    绑定到透明清理):


    您不能通过NetCore中的DI访问Serilog。它是静态的。 在程序.Main()中正确配置和初始化记录器后,只需像启动、控制器等中的任何其他静态程序一样访问即可

    public void ConfigureServices(IServiceCollection services)
                {
        Serilog.Log.Information("here I am in startup");
        //further options
    };
    
    或在顶部添加:

    使用静态Serilog.Log;

    简单地说:


    信息(“击键保存”);

    事实上,我一直在努力使用相同的设置,但我成功地使其工作。解决方案在以下方面与您的代码示例略有不同:

    • 它取决于
      Microsoft.Extensions.Logging.ILogger
    • 使用
      ILogger
    您的控制器代码已经符合这些要求,这就是为什么它可以工作的原因

    using Microsoft.Extensions.Logging;
    
    public class HomeController : Controller
    {
        ILogger _logger;
    
        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
            _logger.LogInformation("Controller instantiated");
        }
    }
    
    使用Microsoft.Extensions.Logging;
    公共类HomeController:控制器
    {
    ILogger\u记录器;
    公共家庭控制器(ILogger记录器)
    {
    _记录器=记录器;
    _logger.LogInformation(“控制器实例化”);
    }
    }
    
    对于其他项目中的其他类,只需确保您依赖默认的ILogger接口,而不是Serilog的实现。这还有一个好处,即如果您以后要替换Serilog,您可以这样做,而不必在其他项目中删除对它的所有引用

    using Microsoft.Extensions.Logging;
    
    public class MyBusinessObject
    {
        ILogger _logger;
    
        public MyBusinessObject(ILogger<MyBusinessObject> logger)
        {
            _logger = logger;
        }
    
        public void DoBusinessLog()
        {
            _logger.Information("Executing Business Logic");
        }
    }
    
    使用Microsoft.Extensions.Logging;
    公共类MyBusinessObject
    {
    ILogger\u记录器;
    公共MyBusinessObject(ILogger记录器)
    {
    _记录器=记录器;
    }
    public void DoBusinessLog()
    {
    _logger.Information(“执行业务逻辑”);
    }
    }
    

    出于某种原因,DI只在需要
    ILogger
    时才实例化一个Logger实例,而不需要
    ILogger
    。为什么我不知道,也许其他人可以回答这个问题。

    谢谢,但我也遇到了同样的问题。我开始怀疑这是否不是Serilog问题,而是DI不工作的问题其他项目周期。例如,我设置了一个存储库并将其注入,它在我的web(根)中工作项目,但当我尝试将其注入其他对象时,它也会抛出一个缺少的param错误。我刚刚创建了一个新项目并得到了相同的结果。是否有可能缺少其他项目对DI的要求?我以前做过这件事,但它“刚刚起作用”。你解决了吗?我有完全相同的问题。出于其他原因(装饰者)我切换到Autofac进行依赖注入,现在它工作正常。很抱歉,我无法确定在切换IOC容器之前是否已修复它。我模糊地记得这是我的Serilog引用的问题。
    using Microsoft.Extensions.Logging;
    
    public class MyBusinessObject
    {
        ILogger _logger;
    
        public MyBusinessObject(ILogger<MyBusinessObject> logger)
        {
            _logger = logger;
        }
    
        public void DoBusinessLog()
        {
            _logger.Information("Executing Business Logic");
        }
    }