Основы .NET Core - поведение инжектора конструктора - PullRequest
0 голосов
/ 01 марта 2019

Я новичок в ядре .NET и хочу начать проект, используя его.Я читаю официальную документацию и учебные пособия.

В официальной документации Microsoft о внедрении зависимостей в разделе « Поведение в конструкторе » объясняется, что «Когда службы разрешенысогласно ActivatorUtilities для внедрения конструктора требуется, чтобы существовал только один применимый конструктор. Перегрузки конструктора поддерживаются, но может существовать только одна перегрузка, аргументы которой могут быть выполнены путем внедрения зависимостей. "

В этом утверждении то, что они подразумевают под"существует только один применимый конструктор"?Может ли кто-нибудь объяснить, пожалуйста.Если есть только один, как он поддерживает перегрузку конструктора.Это немного смущает меня.

PS: - Не стесняйтесь понижать голоса, но, пожалуйста, будьте любезны указать, где я должен задать этот вопрос, в разделе комментариев, если этот вопрос не соответствует критериям.

1 Ответ

0 голосов
/ 01 марта 2019

Это означает, что когда у вас есть класс, который использует 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).

...