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