簡體   English   中英

.NET核心基礎-構造函數注入行為

[英].NET Core fundamentals - Constructor injection behavior

我是.NET Core的新手,我想使用它開始一個項目。 我一直在閱讀官方文檔和教程。

在有關依賴項注入的Microsoft官方文檔中,“ 構造函數注入行為 ”部分中已經說明:“當服務通過ActivatorUtilities解析時,構造函數注入只需要存在一個適用的構造函數。支持構造函數重載,但僅一個重載可以存在,其參數可以全部通過依賴注入來實現。”

在該語句中,“僅存在一個適用的構造函數”是什么意思? 誰能解釋一下。 如果只有一個,它將如何支持構造函數重載。 這讓我有些困惑。

PS:-可以隨意投票,但是如果這個問題不符合標准,請在評論部分中提及我應該在哪里提出這個問題。

這意味着,當您擁有一個使用DI的類時,它必須恰好具有一個構造函數,其中所有參數均為注冊的依賴項(或服務)或具有默認值。

我注意到文檔沒有說明如果這樣會發生什么但是我認為它將拋出異常或以某種方式失敗(例如,工廠方法返回null )。

該文檔還指出:

構造函數可以接受依賴注入未提供的參數,但是參數必須分配默認值。

舉例來說-如果我們有可以使用這些服務的DI上下文:

  • IImageResizerService
  • IImageSavingService
  • IImageObjectRecognizerService

沒關系(單個可滿足的構造函數):

public class DefaultImageProcessingService : IImageProcessingService
{
    public DefaultImageProcessingService
    (
        IImageResizerService          resizer,
        IImageSavingService           saver,
        IImageObjectRecognizerService recognizer,
        String defaultFileName = null,
        Int32  maxSaveAttempts = 3
    )
    {
        this.resizer    = resizer ?? throw new ArgumentNullException( nameof(resizer) );
        this.saver      = saver   ?? throw new ArgumentNullException( nameof(saver) );
        this.recognizer = recognizer?? throw new ArgumentNullException( nameof(recognizer) );
    }
}
  • 它只有1個構造函數
  • 所有構造函數參數均為已注冊服務或具有默認值。

但這不好(多個可滿足的構造函數):

public class DefaultImageProcessingService : IImageProcessingService
{
    public DefaultImageProcessingService
    (
        IImageResizerService resizer,
        String defaultFileName = null,
        Int32 maxSaveAttempts = 3
    )
    {
        this.resizer    = resizer ?? throw new ArgumentNullException( nameof(resizer) );
    }

    public DefaultImageProcessingService
    (
        IImageSavingService saver,
        IImageObjectRecognizerService recognizer,
        String defaultFileName = null,
        Int32 maxSaveAttempts = 3
    )
    {
        this.saver      = saver   ?? throw new ArgumentNullException( nameof(saver) );
        this.recognizer = recognizer?? throw new ArgumentNullException( nameof(recognizer) );
    }
}

這是不可接受的,因為它具有兩個都將服務注冊為參數的構造函數。 因此,DI工廠不知道要使用哪個構造函數,因為它可以使用其中任何一個。

此示例也不可接受(單個無法滿足的構造函數):

public class DefaultImageProcessingService : IImageProcessingService
{
    public DefaultImageProcessingService
    (
        IImageResizerService resizer,
        IImageSavingService saver,
        IImageObjectRecognizerService recognizer,
        IMysteryService mystery,
        String defaultFileName = null,
        Int32 maxSaveAttempts = 3
    )
    {
        this.resizer    = resizer ?? throw new ArgumentNullException( nameof(resizer) );
        this.saver      = saver   ?? throw new ArgumentNullException( nameof(saver) );
        this.recognizer = recognizer ?? throw new ArgumentNullException( nameof(recognizer) );
        this.mystery = mystery ?? throw new ArgumentNullException( nameof(mystery) );
    }
}

這是不可接受的,因為未注冊IMysteryService

沒關系(有多個構造函數,但恰好1個就可以滿足):

public class DefaultImageProcessingService : IImageProcessingService
{
    public DefaultImageProcessingService
    (
        IImageResizerService resizer,
        IImageSavingService saver,
        IImageObjectRecognizerService recognizer,
        String defaultFileName = null,
        Int32 maxSaveAttempts = 3
    )
    {
        this.resizer    = resizer ?? throw new ArgumentNullException( nameof(resizer) );
        this.saver      = saver   ?? throw new ArgumentNullException( nameof(saver) );
        this.recognizer = recognizer?? throw new ArgumentNullException( nameof(recognizer) );
    }

    public DefaultImageProcessingService
    (
        IImageResizerService resizer,
        IImageSavingService saver,
        IImageObjectRecognizerService recognizer,
        IMysteryService mystery,
        String defaultFileName = null,
        Int32 maxSaveAttempts = 3
    )
    {
        this.resizer    = resizer ?? throw new ArgumentNullException( nameof(resizer) );
        this.saver      = saver   ?? throw new ArgumentNullException( nameof(saver) );
        this.recognizer = recognizer ?? throw new ArgumentNullException( nameof(recognizer) );
        this.mystery = mystery ?? throw new ArgumentNullException( nameof(mystery) );
    }
}

這是可以接受的,因為其中一個構造函數僅使用注冊的服務和默認值(第一個構造函數)。 DI工廠將不使用第二個構造函數,因為它具有一個無法滿足的參數( IMysteryService )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM