Уместно ли использовать свойство Injection в базовом классе, когда зависимость требуется только в базовом классе?

Пример:

public abstract class BaseControler : Controller
{
    public IUnitOfWork UnitOfWork { get; set; }
}

public class HomeController : BaseControler
{
    readonly IUserRepository _userRepository;

    // :-)
    public HomeController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }
}

Мы все знаем, что мы должны использовать Инъекции конструктора, когда требуется зависимость. Если это необязательная зависимость, мы можем вместо этого использовать Вложение свойств.

Но что делать, если только ваш базовый класс требует зависимости?

Когда вы будете использовать Инъекция конструктора, вы, на мой взгляд, загрязняете все производные классы.

public abstract class BaseControler : Controller
{
    readonly IUnitOfWork _unitOfWork;

    public BaseControler(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
}

public class HomeController : BaseControler
{
    readonly IUserRepository _userRepository;

    // :-(
    public HomeController(IUserRepository userRepository, 
       IUnitOfWork unitOfWork) : base(unitOfWork)
    {
        _userRepository = userRepository;
    }
}

Согласуется ли использование Инъекции свойств в базовом классе, когда зависимость требуется только в базовом классе?

Ответ 1

Вы не загрязняете производный класс. Вы прямо заявляете потребителю, что этот класс не может функционировать без этой зависимости.

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

Ответ 2

Фактически ваш производный класс IS является базовым классом. Другого объекта нет. Когда вы передаете что-то в базовый конструктор, вы фактически инициализируете тот же объект. И это показывает клиентам, на что зависит ваш экземпляр:

public HomeController(IUserRepository userRepository, IUnitOfWork unitOfWork)

Существует один экземпляр, который зависит от двух вещей: репозитория пользователя и единицы работы. Вызов конструктора базового класса просто удаляет дублирование инициализации из ваших производных классов.