我有一个C#.NET7库,由其他带有扩展方法的WPF/控制台应用程序初始化.库不链接到任何外部日志(log)提供程序,但必须使用主应用程序授予的提供程序.在库服务(如MyLibService1、MyLibService2)中,ILogger<>的依赖项注入效果很好.问题在于登录扩展方法.

以下是库的简化初始化代码:

public static class AddMyLibraryExtensions
{
    public static HostApplicationBuilder AddMyLibrary(this HostApplicationBuilder builder)
    {
        var libConfiguration = builder.Configuration.GetRequiredSection("MyLibrary");

        builder.Services.AddOptions<MyLibrarySettings>()
            .Bind(libConfiguration);
        
        builder.Services.TryAddTransient<IMyLibService1, MyLibService1>();
        builder.Services.TryAddTransient<IMyLibService2, MyLibService2>();

        var libSettings = libConfiguration.Get<MyLibrarySettings>();

        builder.Services.AddDbContext<MyLibDbContext>(opts =>
        {
            opts.UseSqlite(libSettings.ConnectionString);
        });
        
        return builder;
    }
}

它在应用程序中的使用是这样的(CreateApplicationBuilder()有很多好处,所以这里使用它):

static void Main(string[] args)
{
        var builder = Host.CreateApplicationBuilder();
        builder.Services.AddTransient<IAppService1, AppService1>();
        builder.Services.AddTransient<IAppService2, AppService2>();

        builder.AddMyLibrary(); // My library may be added here...

        builder.Services.AddLogging(cfg =>
        {
            var logConf = new LoggerConfiguration()
                .ReadFrom.Configuration(builder.Configuration)
                .CreateLogger();

            Log.Logger = logConf;

            cfg.AddSerilog(logConf); // for example Serilog
        });

        // builder.AddLibrary(); // or here...
        var host = builder.Build();

        var job = host.Services.GetService<IAppService1>();
        job.DoWork();
}

因此,库不知道何时添加日志(log)记录(如果有的话)、添加哪个提供者以及在其扩展方法中不能使用依赖项注入,而且在构建主机之前不能使用主机的ServiceLocator

是否有任何方法可以在AddMyLibrary方法中使用应用程序日志(log)记录(如果有)?

目前,我将One-Send应用程序记录器作为扩展方法的参数,如.AddMyLibrary(对象记录器). 有点难看.

推荐答案

如.AddMyLibrary(对象记录器).

这里能做的事情不多.无论出于何种原因,如果您想在注册期间登录,您需要明确要求提供一个记录器.因此,只需向该方法添加Microsoft.Extensions.Logging.ILogger个参数并使用它:

public static HostApplicationBuilder AddMyLibrary(this HostApplicationBuilder builder, ILogger logger)
{
    logger.Log(...);
}

然后,对于Serilog,您可以使用Serilog.Extensions.Logging使记录器适应微软提供的接口(例如,通过SerilogLoggerProvider).

附注:

另外,在创建这样的扩展方法时,我倾向于提供覆盖所使用的配置节的能力,例如:

public static HostApplicationBuilder AddMyLibrary(this HostApplicationBuilder builder, string cfgSectionPath = "MyLibrary")
{
    builder.Configuration.GetRequiredSection(cfgSectionPath);
}

或者甚至仅仅请求设置(即MyLibrarySettings)作为显式参数.

Csharp相关问答推荐

如何使用FastEndpoints和.NET 8 WebAppliationBuilder进行集成测试?

我应该将新的httpReportMessage()包装在using声明中吗?

如何禁用ASP.NET MVP按钮,以便无法使用开发人员控制台重新启用它

MudBlazor—MudDataGrid—默认过滤器定义不允许用户修改基本过滤器

与C#中的Zip列表并行

UWP中的任务和界面

在实体框架中处理通用实体&S变更跟踪器

附加标题不起作用,而添加则起作用

C#DateTime.ParseExact不使用特定日期

将类移动到新命名空间后更新RavenDB Raven-Clr-Type

在DoubleClick上交换DataGridViewImageColumn的图像和工具提示

在Windows Plesk上发布ASP.NET Core 7 Web API-错误:无法加载文件或程序集';Microsoft.Data.SqlClient';

升级后发出SWITCH语句

在PostgreSQL上使用ExecuteSqlRawAsync的C#11原始字符串文字有区分大小写的问题

Content WithTargetPath实际上是有效的MSBuild项吗?

为什么我的用户界面对象移动到略低于实际目标?

.NET8Blazor-为什么Rapzor渲染在for循环之后显示?

从GRPC连接创建ZipArchive

如何在绑定到数据库的datagridview中向上或向下移动行

如何将 colored颜色 转换为KnownColor名称?