如何为本机库设置单例日志机制

How to setup a singleton log mechanism for native library

提问人:malat 提问时间:11/9/2023 最后编辑:Denis Michealmalat 更新时间:11/9/2023 访问量:54

问:

我正在连接到一个 C 库,该库将日志消息调度到回调。

我很难理解如何在 c# () 中与记录器机制交互。using Microsoft.Extensions.Logging

与其考虑完整的 DI 设置(为了示例),不如假设用户以这种方式设置记录器:

% cat Program.cs
ServiceProvider serviceProvider = new ServiceCollection()
    .AddLogging(loggingBuilder => loggingBuilder
        .AddConsole()
    )
    .BuildServiceProvider();
var logger = serviceProvider.GetService<ILoggerFactory>()!.CreateLogger<Program>();

如何为我的本机库设置单例记录器机制?


作为参考,记录器实现如下:

    public class NativeLoggerForwarder
    {
        private readonly ILogger _logger;
        private readonly Delegate _logDelegate;

        [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        private delegate void LogDelegate(int logLevel, [MarshalAs(UnmanagedType.LPUTF8Str)] string loggerName,
          [MarshalAs(UnmanagedType.LPUTF8Str)] string logMessage);

        [DllImport("NativeLibrary.dll")]
        private static extern void configure_callback(IntPtr aCallback);

        private static Delegate ConfigureListener(Action<int, string, string> logMessage)
        {
            var logDelegate = new LogDelegate(logMessage);
            var ptr = Marshal.GetFunctionPointerForDelegate(logDelegate);
            configure_callback(ptr);
            return logDelegate;
        }

        private void LogMessage(int logLevel, string loggerName, string message)
        {
            _logger.Log((LogLevel)logLevel, $"{loggerName} - {message}");
        }

        public NativeLoggerForwarder(ILogger logger)
        {
            this._logger = logger;
            this._logDelegate = ConfigureListener(this.LogMessage);
        }
    }

手动实例化将是(一旦记录器实例可用):

var manualInstantiation = new NativeLoggerForwarder(logger);

如何用自动单例 (DI) 替换上述内容?

C# net-6.0 pinvoke iLogger

评论

0赞 Simon Mourier 11/9/2023
你们在找这个吗?learn.microsoft.com/en-us/dotnet/core/extensions/......
0赞 malat 11/9/2023
@SimonMourier在我的用例中,我无法理解该文档:[...]once a logger instance is available
0赞 Simon Mourier 11/9/2023
不知道你这是什么意思。对于任何自定义记录器类,必须创建至少 1 个 ILogger 实现类(将调用内部记录器)和 1 个 ILoggerProvider 实现类。或者,您可以添加选项。然后,可以创建一个扩展方法(如我的链接中的 ColorConsoleLoggerExtensions.AddColorConsoleLogger),调用方使用该方法将 ILoggerProvider 注册为单一实例。
0赞 ThomasArdal 11/10/2023
你不能把你的本地记录器注册为单例吗?services.AddSingleton(manualInstantiation);

答: 暂无答案