Это зависит от того, как вы это настраиваете. Как правило, вы будете довольно ограничены в базовом классе, поскольку он будет иметь видимость только для себя, а не для классов, производных от него. Вы можете добавить абстрактное свойство или метод, но это только гарантирует, что оно «реализовано», а не реализовано правильно. Например, допустим, вы хотите заставить разработчиков реализовать CheckValidation
, сделав его абстрактным. Следующее в производном классе будет удовлетворять:
protected override bool CheckValidation() => true;
Что, очевидно, на самом деле ничего не решает.
В конечном счете, если есть какой-то класс проверки, который вы предоставляете с помощью композиции, было бы лучше внедрить его в базовый класс:
public abstract class CommandHanlder<TCommand> : IRequestHandler<TCommand, ICommandResult>
where TCommand : IRequest<ICommandResult>
{
protected readonly IValidationClass _validationClass;
protected CommandHandler(IValidationClass validationClass)
{
_validationClass = validationClass ?? throw new ArgumentNullException(nameof(validationClass));
}
...
}
Тогда производные классы должны будут предоставить аналогичный конструктор:
protected MyDerivedCommandHandler(MyValidationClass validationClass)
: base(validationClass)
Это будет гарантировать, что если не будет передана какая-либо реализация IValidationClass
, будет сгенерировано исключение.
Если не считать этого, а может быть, и лучше, это простой обзор кода. Должен быть конвейер сборки и выпуска. Слияние с основной веткой / веткой релиза должно выполняться с помощью запросов извлечения, и для этих запросов извлечения требуется один или несколько проверяющих. Если кто-то добавляет подобный класс без «проверки», вы можете отклонить запросы извлечения, отправив их разработчику для исправления.