至此,我正在尝试在我的Clean Architecture SPA核心应用程序中为Autofac实现Serilog上下文记录器注入。
项目结构:
在我的项目中,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集成的正确方法是什么?
使用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
就取决于口味/意见,因为依赖解析器将正确解析所有注册(Autofac
和IServiceCollection
)。我更喜欢通过内置的IServiceCollection
保留注册,因为它们是标准的并且更熟悉的方法。因此,我将保留UseSerilog()
版本。
更新:出于第二种想法,您必须使用UseSerilog()
,因为这是用于记录ASP.NET Serilog
的ILoggerFactory
实现的寄存器。另一方面,builder.RegisterLogger();
仅向Autofac注册Serilog的ILogger
。它不会将任何内容连接到MVC。
关于InitializeWeb
项目中的CL
方法,将ASP.NET Core和数据层依赖项混合在一个DLL中时,请注意。如果CL
项目可能会在可重复使用的Nuget
包中演变为多个项目,则在dll中具有ASP.NET Core的硬编码版本可能会成为问题。
在我的Clean项目中实现SerilogAutofac集成的正确方法是什么?