[英]Passing Services using Dependency Injection and Factory Pattern in ASP.NET
我正在使用ASP.NET Core,我知道框架已經提供了這樣的Logging機制,但是使用它來說明我的問題。
我正在使用一種Factory模式來構建Logger類,因為我不知道日志記錄的類型(因為它存儲在DB中)。
ILogger合同
Log(string msg)
然后,在根據從DB傳遞的參數創建Logger之后,LoggerFactory將返回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");
}
但是,我打算在沒有任何實例化的情況下保留我的類,我需要在MyService中使用Constructor DI,我需要在Startup上注入所有依賴項:
services.AddTransient<Contracts.ILogger, LoggerFactory.BuildLogger("param") > ();
但這不起作用,我們需要通過一個具體的實現。 如何使用DI來完成這項工作,是否有更好的方法來實現它?
您的方法中存在一些錯誤:
LoggerFactory
類型,該類型是依賴性反轉原則違規。 ILogger
是您的消費者所依賴的真實服務這一事實。 這使得系統更難以測試,更難以維護,並使對象圖分析變得復雜。 相反,您的服務應如下所示:
public class MyService
{
private ILogger _logger;
public MyService(ILogger logger)
{
_logger = logger;
}
}
這大大簡化了依賴ILogger
所有消費者。 這也意味着為MyService
獲取正確的ILogger
將成為Composition Root的責任,這是獲得這些知識的正確位置。
但這確實意味着您可能需要從ASP.NET Core的內置DI容器轉移到功能更豐富的DI庫,因為內置容器無法在ILogger
進行上下文感知注冊時庫自動連接其他構造函數依賴項。
使用ASP.NET Core DI容器,您只能使用委托手動連接服務。 例如:
services.AddTransient<MyService>(c => new MyService(
BuildLogger(typeof(MyService).Name),
c.GetRequiredService<ISomeOtherDependency>(),
c.GetRequiredService<IYetAnotherOne>());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.