I'm using the latest NLog, ASP.NET Core, EF Core.
I wrote a custom log target which saves via EF:
public class MyEFTarget : TargetWithLayout
{
private readonly IMyContext _context;
public MyEFTarget(IMyContext context) : base()
{
_context = context;
}
protected override void Write(LogEventInfo logEvent)
{
// and so on...
}
}
My Startup:
public void ConfigureServices(IServiceCollection services)
{
// register context with DI (as scoped)
services.AddDbContext<MyContext>(o => o.UseSqlite(config.GetConnectionString("Default")));
services.AddScoped<IMyContext, MyContext>();
// target depends on context, so must also be registered with DI
// I chose scoped so it's the same as the context
services.AddScoped<MyEFTarget>();
// ...and so on
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
// normal NLog config
env.ConfigureNLog("NLog.config");
loggerFactory.AddNLog();
app.AddNLogWeb();
// register target
Target.Register<MyEFTarget>("MyEFTarget");
// add target + rule programmatically
var target = serviceProvider.GetService<MyEFTarget>();
var rule = new LoggingRule("*", LogLevel.Info, target);
LogManager.Configuration.AddTarget("MyEFTarget", target); // problem is here ********
LogManager.Configuration.LoggingRules.Add(rule);
LogManager.ReconfigExistingLoggers();
// ...and so on
}
The problem is that NLog caches the target instance for the duration of the app...I assume? So it's basically a singleton. And it's keeping a reference to my EF context, which might be disposed.
Is there a better way?
To restate the problem generically (because it's not an EF issue), "how do I register/add a custom target which has short-lived dependencies"?