I'm designing a framework which users can extend. Basically I will provide them a set of interfaces which they can implement, and my "manager" class will call their implementations like this:
abstract1 = factory.GetConcreteExtension1()
abstract2 = factory.GetConcreteExtension2()
abstract1.DoSomething(abstract2)
Where my client implements the concrete version of the abstractions. However they might decide to add data to concrete2 which is not in the abstract2 interface. This will force them to downcast abstract2 to concrete2 in concrete.DoSomething implementation.
This looks like a code smell because I force them to implement a method (DoSomething) which in its signature expects abstract1 but actually can only get concrete1 (plus I force them to write the casting).
I can't find a solution that both keeps contract well defined and allows my framework to manage the process by itself. Any ideas?