Я разрабатываю фреймворк, который пользователи могут расширять.
По сути, я предоставлю им набор интерфейсов, которые они могут реализовать, и мой класс «manager» будет вызывать их реализации следующим образом:
abstract1 = factory.GetConcreteExtension1()
abstract2 = factory.GetConcreteExtension2()
abstract1.DoSomething(abstract2)
Где мой клиент реализует конкретную версию абстракций.
Однако они могут решить добавить данные в concrete2, которого нет в интерфейсе abstract2.
Это заставит их понижать abstract2 к concrete2 в concrete.DoSomething.
Это похоже на запах кода, потому что я заставляю их реализовать метод (DoSomething), который в своей подписи ожидает abstract1, но на самом деле может получить только конкретный1 (плюс я заставляю их писать приведение).
Я не могу найти решение, которое бы одновременно четко определяло контракт и позволяло моей платформе самостоятельно управлять процессом. Есть идеи?