2017-07-16 19 views
2

我將盡可能最好地解釋我的情況,我希望它是有道理的。當EF遷移沒有經過Program.cs時,在Program.cs中配置依賴關係(例如日誌記錄)

我的項目是一個.NET核心Web API。有一個獨立的類庫項目,其中包含模型,包括我的DbContext的東西。

問題#1 我希望能夠記錄從內Startup.cs

理由安慰:我目前正在調試從環境變量設置的變量。我想輸出已設置爲控制檯的內容。

實施例:How do I write logs from within Startup.cs

現在,解決方案是ILoggerFactory Program.cs中添加到服務容器中,例如:

var host = new WebHostBuilder() 
     .UseKestrel() 
     .ConfigureServices(s => { 
      s.AddSingleton<IFormatter, LowercaseFormatter>(); 
     }) 
     .ConfigureLogging(f => f.AddConsole(LogLevel.Debug)) 
     .UseStartup<Startup>() 
     .Build(); 

     host.Run(); 

接下來,更改Startup.cs構造採取ILoggerFactory即會從我們剛剛註冊的容器中取出。如下:

public class Startup { 

    ILogger _logger; 
    IFormatter _formatter; 

    public Startup(ILoggerFactory loggerFactory, IFormatter formatter){ 
    _logger = loggerFactory.CreateLogger<Startup>(); 
    _formatter = formatter; 
    } 

    public void ConfigureServices(IServiceCollection services) { 
    _logger.LogDebug($"Total Services Initially: {services.Count}"); 

    // register services 
    //services.AddSingleton<IFoo, Foo>(); 
    } 

    public void Configure(IApplicationBuilder app, IFormatter formatter) { 
    // note: can request IFormatter here as well as via constructor 
    _logger.LogDebug("Configure() started..."); 
    app.Run(async (context) => await context.Response.WriteAsync(_formatter.Format("Hi!"))); 
    _logger.LogDebug("Configure() complete."); 
    } 

這解決了我的問題 - 我可以運行應用程序,它現在工作正常,記錄我需要它的地方。

然而,

當我再嘗試運行的dotnet EF數據庫更新--startup項目= myAPIProject

現在失敗了,因爲EF沒有通過Program.cs中去,它,而不是試圖直接實例我啓動類。因爲現在我的構造函數需要一個ILoggerFactory,EF不知道該做什麼並拋出一個異常。

有沒有人知道解決這個問題的方法?

回答

1

好的,所以我找到了解決方案。

而不是將ILoggerFactory傳遞給Startup.cs構造函數。通ILogger如下:

private ILogger<Startup> _logger; 
    public Startup(IHostingEnvironment env, ILogger<Startup> logger) { 
     _env = env; 
     _logger = logger; 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
      .AddEnvironmentVariables(); 

      _configuration = builder.Build(); 
    } 

我Program.cs的樣子:

var host = new WebHostBuilder() 
      .UseKestrel() 
      .UseConfiguration(config) 
      .ConfigureServices(s => s.AddSingleton<IConfigurationRoot>(config)) 
      .ConfigureLogging(f => { 
       f.AddConsole() 
       .AddDebug(); 
      }) 
      .UseContentRoot(Directory.GetCurrentDirectory()) 
      .UseIISIntegration() 
      .UseStartup<Startup>() 
      .Build(); 

     host.Run(); 

這是因爲通過EF遷移運行,即使我們的創業構造函數將被傳遞ILogger由DI容器(和我們的天堂」配置一個記錄器)。

我看完之後想通了這一點:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup(「服務可在啓動下)

現在......我都遇到過這麼多令人沮喪的問題,像這樣與.NET的核心我猜它可能是。因爲它仍然處於起步階段,最佳實踐文件等仍在改進中,因爲我讀過的大多數指南都沒有這樣做過,所以我覺得這也是部分原因,配置「在.NET核心 - 這顯然帶來了不利因素。與C#這樣的強類型語言一起工作的美妙之處在於,運行時可以讓編譯器幫助您識別像這樣的問題。

(記住,一切工作正常與ILoggerFactory,直到您運行使用不具有訪問Program.cs中增值服務EF遷移)

熱衷於聽到這個民族的思想。我相信其他人肯定會遇到同樣的挫折。不要誤解我的意思我很喜歡.NET核心,但是在開發這個應用程序的過程中,我一直被困在這樣的最簡單的愚蠢問題上幾個小時(有時候更長)編寫代碼。

+0

是的,你會看到ASP.NET Core 2.0移向這個模型,所以Startup中可以使用日誌記錄。另請參閱此處:https://ardalis.com/logging-and-using-services-in-startup-in-aspnet-core-apps – ssmith