I am slowly converting a leagacy application into MVC style (at the moment for new code and for massively changed code). At the moment the controllers are created on demand:
FooController := TFooController.Create(GuiProvider, Model);
FooController.EditFoo(); //show Edit-Dialog for Foo
As more and more of the code is converted I want to create a main class (TMainController), that provides the controllers:
FooController := MainController.GetFooController();
FooController.EditFoo();
My problem is, that I need to access the other controllers inside one controller. (For instance I need to access BarController inside of FooController).
Any idea how to solve this cleanly? Or maybe my base idea is flawed?
Possible solutions I considered:
Solution 1 (not working):
My first idea was to provide every controller with an reference to TMainController:
//Edit-Dialog for Foo contains a button to edit Bar that belongs to Foo
procedure FooController.PerformActionEditBarOfFoo();
begin
//do something
BarController := FMainController.GetBarController();
BarController.EditBar()
//do some other things
end;
But this wont work, because of circular unit references. Because TMainController needs to know every other controller and every other controller needs a reference to TMainController.
Solution 2 (working but ugly):
A workaround to solution 1 would be to create an base class to TMainController. Then I could pass this base class to the other controllers and would need to cast to TMainController to access the other controllers:
procedure FooController.PerformActionEditBarOfFoo();
begin
//do something
BarController := (FMainBaseController as TMainController).GetBarController();
BarController.EditBar()
//do some other things
end;
This works, but this seems more like a hack.
Solution 3 (nearly impossible)
An other solution would be to provide all needed controllers at the creation of FooController. But this can be huge if BarController for instance needs other controllers and so on.
Solution 4 (impossible for me)
An other solution might be the usage of an Dependency Injection Framework like Spring. But I cannot promote such radical changes in the existing code.