I'm attempting to build a web front-end based on the MVC pattern, as opposed to based on the libraries involved (e.g. React.js).
I'm using constructor-based dependency injection and interfaces to de-couple the implementations of each element (of MVC), but this still leaves a circular dependency.
- Controller depends on Model (to respond to end-user events).
- Model depends on View (to re-render updated model).
- View depends on React Component (for implementation).
- React Component depends on Controller methods (to allow for end-user input).
I've broken this circular dependency by using mutator-based dependency injection with the View, like so:
view = new View() model = new Model(view) controller = new Controller(model) component = new Component(controller.onClick) view.component = component
...which works, but it leaves me with a problem.
As the Component dependency in the View is mutator-injected, it won't be available (for use) until the injection actually happens.
Yet my Model is doing some initialization before the mutator-injection occurs and because the View doesn't have a Component to operate, it just does nothing (until it does have a Component).
I'm thinking I can solve this by storing pending View updates (within the View implementation) and then replaying them in order when the Component becomes available.
Is there a better approach to this?
Thanks to John for pointing out that I have my Model <--> View dependencies the wrong way around.
Yet if I fix them to get this:
model = new Model() controller = new Controller(model) component = new Component(controller.onClick) view = new View(model, component)
...that does allow me to use constructor-based dependency injection all around, but my original problem still persists.
I.e. If my Model does some initialization before the View subscribes to its update broadcasts, then those initial broadcasts will not make it to the View (and hence the end-user).
I'm thinking that I'll just have to try and delay these Model initializations until after the View has subscribed to the Model updates.
Am I missing another approach?