Как ограничить класс декоратором что бы не подменяли тип после наследования от открытого интерфейса?

Мне необходимо ограничить использование интерфейсов наследуемых от интерфейса IOptions, т.к. это просто декоратор для интерфейса IApiEx<TOptionsType, TResultType> и IApi<TOptionsType, TResultType>.

Т.к. я не смогу контролировать то что будет передаваться в методы через интерфейс, мне нужно как-то ограничить наследуемые публичные классы от того что бы не мог пользователь просто написать новый класс с унаследованием от интерфейса к примеру ISearchOptions и сделать так что бы к примеру из метода Uri Zip(); будет возвращаться null.

Это можно как нибудь проверить и быть уверенным в том что например у меня есть класс SearchOptions, и как-то жестко проверить является ли интерфейс именно этим классом, а не каким нибудь левым?

Или же может можно подставить какой нибудь класс/интерфейс декоратор который не позволит подставить левый класс?

Диаграмма


Ответы (1 шт):

Автор решения: Alexander Petrov

Давайте попробуем разобрать разные варианты.

  1. Проверять тип в рантайме. Если передан неправильный тип, бросать исключение или ещё как-то реагировать. Это гарантирует правильную работу (после устранения ошибок), но выявится только в процессе исполнения.

  2. Передавать конкретный тип, а не интерфейс. Если уж есть требования на точный тип, то его и используйте. Вроде, всё просто.

  3. Написать тест(ы). В тесте проходим по всем сборкам проекта, находим все типы, реализующие этот интерфейс. И проверяем, не появилось ли лишних типов. Если есть лишние - билд-процесс прерывается. Имхо, способ может гарантировать надёжность. Но нужен налаженный CI.

  4. Развитие предыдущего способа. Написать Roslyn-analyzer. Этот анализатор делает то же, что и тест: ищет типы, реализующие интерфейс. В него жёстко забиты разрешённые типы. Достоинство: выдаёт предупреждения прямо по ходу написания кода. Недостаток: при малейшем изменении разрешённых типов нужно переписывать анализатор (перекомпилировать, деплоить, подключать к проекту). Ну и конечно, анализатор должен быть подключен к проекту. И программисты должны писать код не в Блокноте, а в IDE, которая поддерживает анализаторы.

→ Ссылка