在Clean Architecture中为Autofac实现Serilog上下文记录器注入的正确方法是什么?

问题描述 投票:2回答:2

至此,我正在尝试在我的Clean Architecture SPA核心应用程序中为Autofac实现Serilog上下文记录器注入。

项目结构:

enter image description here

enter image description here

在我的项目中,Autofac处于如下所示的Infrastructure CL项目中:

参考代码:

public static class ContainerSetup
{
    public static IServiceProvider InitializeWeb(Assembly webAssembly, IServiceCollection services) =>
        new AutofacServiceProvider(BaseAutofacInitialization(setupAction =>
        {
            setupAction.Populate(services);
            setupAction.RegisterAssemblyTypes(webAssembly).AsImplementedInterfaces();
        }));

    public static Autofac.IContainer BaseAutofacInitialization(Action<ContainerBuilder> setupAction = null)
    {
        var builder = new ContainerBuilder();

        var coreAssembly = Assembly.GetAssembly(typeof(BaseEntity));
        var infrastructureAssembly = Assembly.GetAssembly(typeof(P2PRepository));
        builder.RegisterAssemblyTypes(coreAssembly, infrastructureAssembly).AsImplementedInterfaces();

        setupAction?.Invoke(builder);
        return builder.Build();
    }
}

并在启动类中注册Autofac容器,如下所示:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<ApplicationUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddIdentityServer()
        .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

    return ContainerSetup.InitializeWeb(Assembly.GetExecutingAssembly(), services);
}

我已经尝试了什么?

我已经在我的Web项目中成功实现了Serilog

public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
        .Enrich.FromLogContext()
        .WriteTo.Console()
        .WriteTo.File(
            @"D:\home\LogFiles\Application\myapp.txt",
            rollingInterval: RollingInterval.Day,
            outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
            )
        .CreateLogger();

        try
        {
            Log.Information("Starting web host");
            CreateWebHostBuilder(args).Build().Run();
            return 0;
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseSerilog();
}

在serilog及其相关性之上实现之后,我发现Serilog也正在为Autofac提供实现。因此,我很困惑应该在Web项目或Infrastructure Project中在哪里使用Serilog的实际实现?是否应该使用以下代码从program.cs文件中还原所有代码并实施Serilog并将其依赖项安装在Infrastructure项目中?

首先安装Serilog依赖项:

安装包AutofacSerilogIntegration

Then when configuring the Autofac container, call RegisterLogger():

Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();

var builder = new ContainerBuilder();

var coreAssembly = Assembly.GetAssembly(typeof(BaseEntity));
var infrastructureAssembly = Assembly.GetAssembly(typeof(P2PRepository));
builder.RegisterAssemblyTypes(coreAssembly, infrastructureAssembly).AsImplementedInterfaces();

setupAction?.Invoke(builder);
builder.RegisterLogger(); // Here register serilog
return builder.Build();

简单的问题是:

在我的Clean项目中实现SerilogAutofac集成的正确方法是什么?

c# asp.net-core autofac serilog clean-architecture
2个回答
0
投票

使用ASP.NET Core 2.1]和2.2进行连接Autofac的推荐方法是使用:

services.AddAutofac();

官方文档中的代码示例说明了您返回IServiceProvider的方法:

是旧的,不推荐使用的方法,在ASP.NET Core中不支持3.0 +。

Autofac向服务注册后,您只需要使用Startup类中的方法来注册依赖项:

public void ConfigureContainer(ContainerBuilder builder)
{
    // Register your own things directly with Autofac, like:
    builder.RegisterModule(new MyApplicationModule());
}

链接到文档是here

一旦正确连接了Autofac后,注册Serilog就取决于口味/意见,因为依赖解析器将正确解析所有注册(AutofacIServiceCollection)。我更喜欢通过内置的IServiceCollection保留注册,因为它们是标准的并且更熟悉的方法。因此,我将保留UseSerilog()版本。

更新:出于第二种想法,您必须使用UseSerilog(),因为这是用于记录ASP.NET SerilogILoggerFactory实现的寄存器。另一方面,builder.RegisterLogger();仅向Autofac注册Serilog的ILogger。它不会将任何内容连接到MVC。

关于InitializeWeb项目中的CL方法,将ASP.NET Core和数据层依赖项混合在一个DLL中时,请注意。如果CL项目可能会在可重复使用的Nuget包中演变为多个项目,则在dll中具有ASP.NET Core的硬编码版本可能会成为问题。


0
投票

在我的Clean项目中实现SerilogAutofac集成的正确方法是什么?

© www.soinside.com 2019 - 2024. All rights reserved.