To the point, I'm trying to implement Serilog Contextual logger injection for Autofac in my Clean Architecture SPA core application.
Project Structure:
In my project, Autofac is in Infrastructure CL project like below:
Reference code:
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();
}
}
and register Autofac container in Startup class like below:
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);
}
What I've tried yet?
I've successfully implement Serilog in my web project
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();
}
after implementation above serilog and its dependencies, I've found that Serilog is giving implementation for Autofac also. So, I'm confused where should I used actual implementation of Serilog either in web project or Infrastructure Project? Should I revert back all code from my program.cs
file and implement Serilog and install it dependencies in Infrastructure project by using below code?
First install Serilog Dependency:
Install-Package 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();
Simple question is:
What is the proper way to implement SerilogAutofac integration in my Clean project?
What is the proper way to implement SerilogAutofac integration in my Clean project?
This is opinion based question meaning there is no single answer to this.
In my opinion, keep in mind that to implement Serilog Contextual logger injection for Autofac, you are doing two things:
The code in Main
is for the first purpose as per the instruction. And remember, this is purely Serilog to integrate with ASP.Net Core. So, by far, no Autofac involved. That, if you remove Autofac dependency from your projects, your application should still be using Serilog.
The code in ContainerSetup
is where you introduced Autofac to ASP.NET Core, and from that on, ASP.NET Core knows to use Autofac as the DI container. If you want to specifically configure contextual loggers using Autofac, then ContainerSetup
is the correct place to do so.
Having that said, to help decide where to configure the loggers, ask yourself a simple question:
Do you want Serilog regardless of Autofac?
If yes, then do not initialize Serilog loggers in your Autofac specific types.