Ответ 1
Не обязательно плохо смешивать инжекцию конструктора и вложение свойств, но это может быть не так уж и просто. В качестве общей стратегии избегайте Property Injection, поскольку ее гораздо сложнее реализовать правильно (это может показаться противоречивым, но это правда).
Важно понимать, когда использовать каждый шаблон.
- Конструкция Инъекция должна быть вашим шаблоном инъекции по умолчанию. Он очень прост в реализации и может гарантировать инварианты: назначьте его в поле только для чтения, чтобы обеспечить потребительские инварианты.
- Вложение свойств может использоваться, когда у вас есть хорошая локальная настройка по умолчанию, но вы хотите следовать Open/Closed Principle и позволяют продвинутым пользователям расширять класс, предоставляя альтернативную реализацию.
Вы никогда не должны применять свойство Injection из-за конструкторской косметики.
Если вам требуется слишком много зависимостей, это признак того, что вы можете нарушать принцип единой ответственности - класс просто пытается сделать слишком много сразу.
Вместо того, чтобы вводить объект Parameter (в противном случае это хорошее предложение), лучшим вариантом является инкапсуляция двух или более зависимостей в службу агрегации, которая организует взаимодействие этих зависимостей.
Представьте, что ваш первоначальный конструктор выглядит так:
public MyClass(IDep1 dep1, IDep2 dep2, IDep3 dep3, IDep4 dep4, IDep5 dep5)
После применения небольшого анализа вы выясните, что в этом случае IDep1, IDep3 и IDep4 будут использоваться вместе определенным образом. Это позволит вам ввести службу агрегирования, которая инкапсулирует их следующим образом:
public class AggService : IAggService
{
public AggService(IDep1 dep1, IDep3 dep3, IDep4 dep4)
{
// ...
}
// ...
}
Теперь вы можете переписать исходный конструктор:
public MyClass(IAggService aggSrvc, IDep2 dep2, IDep5 dep5)
и т.д.
Очень часто, что совокупная услуга оказывается правильной концепцией в ее собственном праве, и внезапно у вас есть более богатый API, чем когда вы начали.