2017-03-06 66 views
0

註冊NLog目標(具有依賴關係)我正在使用最新的NLog,ASP.NET Core,EF Core。使用ASP.NET Core的DI

我寫了通過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... 
    } 

} 

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 
} 

的問題是,NLOG緩存target實例應用程序的時間...我假設?所以它基本上是一個單身人士。它保留了對我的EF上下文的引用,這可能會被處理。

有沒有更好的方法?

爲了一般地重申問題(因爲它不是EF問題),「我如何註冊/添加具有短暫依賴關係的自定義目標」?

+0

您可以創建一個沖洗模式,沖洗時只開放數據庫連接。如果你可以在需要時注入IServiceProvider和'GetService ()'。 –

+0

@JoelHarkes連接由EF處理,我無法控制它。 – grokky

+0

爲什麼你使用AddScoped如果你有services.AddDbContext? – Alexan

回答

1

當NLog配置被加載後,NLog將用ConfigurationItemFactory.Default.CreateInstance創建一個目標實例,並且只有在重新加載配置時纔會重新創建目標。

如果你需要一個新的EF上下文每一次,我會建議加載EF上下文protected override void Write(LogEventInfo logEvent)

+0

嗯,這有點棘手。要在那裏創建一個上下文,你需要某種依賴。但是構造函數注入傳遞的任何依賴都會被應用程序的整個生命週期緩存。和以前一樣的問題。我想我需要使用服務定位器模式。呸! :-) – grokky

+0

你給了我一個想法,我[分開發布](https://stackoverflow.com/questions/42716038/is-it-safe-to-cache-iserviceprovider-for-an-apps-lifetime) 。一旦我弄明白了,我會更新這個問題。感謝您讓我走上正軌。 – grokky

+0

這就是我目前正在做的,但它需要很大的努力才能正常工作。不幸的是,NLog不允許通過lambda/factory添加自定義目標,所以每次都創建一個新目標,從而允許目標擁有自己的非單例依賴關係。不過,這讓我走上了正軌。 – grokky

相關問題