Как ограничить класс декоратором что бы не подменяли тип после наследования от открытого интерфейса?
Мне необходимо ограничить использование интерфейсов наследуемых от интерфейса IOptions, т.к. это просто декоратор для интерфейса IApiEx<TOptionsType, TResultType> и IApi<TOptionsType, TResultType>.
Т.к. я не смогу контролировать то что будет передаваться в методы через интерфейс, мне нужно как-то ограничить наследуемые публичные классы от того что бы не мог пользователь просто написать новый класс с унаследованием от интерфейса к примеру ISearchOptions и сделать так что бы к примеру из метода Uri Zip(); будет возвращаться null.
Это можно как нибудь проверить и быть уверенным в том что например у меня есть класс SearchOptions, и как-то жестко проверить является ли интерфейс именно этим классом, а не каким нибудь левым?
Или же может можно подставить какой нибудь класс/интерфейс декоратор который не позволит подставить левый класс?
Ответы (1 шт):
Давайте попробуем разобрать разные варианты.
Проверять тип в рантайме. Если передан неправильный тип, бросать исключение или ещё как-то реагировать. Это гарантирует правильную работу (после устранения ошибок), но выявится только в процессе исполнения.
Передавать конкретный тип, а не интерфейс. Если уж есть требования на точный тип, то его и используйте. Вроде, всё просто.
Написать тест(ы). В тесте проходим по всем сборкам проекта, находим все типы, реализующие этот интерфейс. И проверяем, не появилось ли лишних типов. Если есть лишние - билд-процесс прерывается. Имхо, способ может гарантировать надёжность. Но нужен налаженный CI.
Развитие предыдущего способа. Написать Roslyn-analyzer. Этот анализатор делает то же, что и тест: ищет типы, реализующие интерфейс. В него жёстко забиты разрешённые типы. Достоинство: выдаёт предупреждения прямо по ходу написания кода. Недостаток: при малейшем изменении разрешённых типов нужно переписывать анализатор (перекомпилировать, деплоить, подключать к проекту). Ну и конечно, анализатор должен быть подключен к проекту. И программисты должны писать код не в Блокноте, а в IDE, которая поддерживает анализаторы.
