2

我使用的是ASP.NET Core,我知道這樣的日誌記錄機制已經由框架提供,但是使用它來說明我的問題。因爲我不知道日誌類型(因爲它存儲在數據庫中),所以我使用了一種Factory模式來構建Logger類。在ASP.NET中使用依賴注入和工廠模式傳遞服務

的ILogger合同

Log(string msg) 

隨後的LoggerFactory將根據PARAM從DB通過創建一個記錄器後返回ILogger:

public class LoggerFactory 
{ 
    public static Contracts.ILogger BuildLogger(LogType type) 
    { 
     return GetLogger(type); 
    } 

//other code is omitted, GetLogger will return an implementation of the related logger 

現在,當我需要使用Logger我要這樣做:

public class MyService 
{ 
    private ILogger _logger 
    public MyService() 
    { 
     _logger = LoggerFactory.BuildLogger("myType"); 
    } 

但是,我打算讓我的課沒有任何insta ntiation,我需要使用構造DI爲MyService中,我需要注入在啓動時所有的依賴:

services.AddTransient<Contracts.ILogger, LoggerFactory.BuildLogger("param") >(); 

但是這不會工作,這一點,我們需要通過一個具體的實現。 如何使用DI進行這項工作,是否有更好的方法來實現?

+0

一種選擇是注入'LoggerFactory',而不是'ILogger'。通過這種方式,您可以獲得LoggerFactory,從數據庫獲取Type並構建您的ILogger。如果你想注射ILogger,你必須知道注射時刻你的ILogger的類型。但是你可能還沒有這個信息。 –

+0

您的意思是在MyService構造函數中傳遞LoggerFactory,並且不要將其添加到.net核心服務 – Coding

+0

是的。像這樣:'services.AddSingleton ();'。 Singleton意味着你只會在第一次需要的時候創建一個LoggerFactory對象。在此之後,您將只使用相同的。然後,像這樣使用:'public MyService(LoggerFactory loggerFactory){....}' –

回答

3

有一對夫婦在你的方法錯誤:

相反,你的服務應如下所示:

public class MyService 
{ 
    private ILogger _logger; 
    public MyService(ILogger logger) 
    { 
     _logger = logger; 
    } 
} 

這大大簡化了依靠​​所有消費者。這也意味着獲得​​MyService成爲Composition Root的責任,這是獲得這些知識的正確位置。

但這意味着您可能需要從ASP.NET Core的內置DI容器轉移到更多功能豐富的DI庫,因爲內置容器無法進行上下文感知註冊對於​​,同時讓庫自動連接其他構造函數依賴關係。

使用ASP.NET Core DI容器,您只能使用代理手動連接您的服務。例如:

services.AddTransient<MyService>(c => new MyService(
    BuildLogger(typeof(MyService).Name), 
    c.GetRequiredService<ISomeOtherDependency>(), 
    c.GetRequiredService<IYetAnotherOne>()); 
+0

Steven,用你的例子,他不能注入正確的ILogger,對吧?如果他在實例化'MyService'之前知道類型,那麼他可以將構造函數更改爲'public MyService(ILogger logger)'。但由於他不知道,他必須注入一個可以爲他做到這一點的界面。如我錯了請糾正我。 –

+2

@FabricioKoch:我不知道我跟着你。除此之外,我不建議在這裏引入一個通用抽象,因爲'MyService'對這個泛型完全不感興趣;它只是希望登錄。因此,成分根源是提供正確類型的問題,而不是消費者。 – Steven

+0

@Steven,我從你那裏瞭解到,這不適用於ASP Core DI容器,因爲它不提供組合根目錄?如果答案是肯定的,那麼如何使用Ninject或AutoFac等其他庫? – Coding