Subcomponents & dependencies

Notice: This thread is very old.
Nox
Member | 378
+
0
-

Hi,

'm wondering how to proceed when using DI and components with subcomponents. Presenter is fine, he can pretty much reach to any functionality by $this->context->(someService).

tl;dr: With components, we can pass dependencies by constructor. But when those components have subcomponents and need their dependencies to pass into their constructor it gets trickier/bloated.

Too long stuff:
The subcomponents probably be similar to component, but I can't say this for sure. Even if they're similar, they can use a bit different services, resulting in theoretical need to pass every direct and indirect dependency into the parental component.

  • Container … I try to avoid using containers for the reasons listed on miskohevery, you just don't see what you're supposed to pass into the class. This sounds as convenient in this case but imho due to this even worse
  • Have the components tied more closely to the presenter… and allow them to fetch the stuff by themselves. Well…and we don't have DI anymore…although components are pretty close to Presenter if I understand correctly (therefore it's ok for them to contact the presenter in some cases…please correct me if 'm wrong), still this could seem like an abuse of this (ser.locator)

Can't really think of anything else (except of just resign and pass everything)

Restricting subcomponents to the same dependencies as their parent doesn't seem viable in practice, or could result in bloated services perhaps

One example: Stopwatch* is related to Tasks, just measures time but coupled with task it can measure how much time specific one of them took and also add it to Task's Project total time and stuff.
As for components the UI\Stopwatch itself just needs the Service\Stopwatch, but with Tasks it would also need a service for Tasks and service for cooperation of Tasks and Stopwatch and Project (I called it Service\Measurer, but that can be changed)…and this is probably not the worst case

*) not just component, rather a whole functionality split to service, loader, entity and ui (component)…

is the example poorly designed? anyway the example might be bad but the issue still apply even in clean cases, I dunno …

Thanks for feedback

HosipLan
Moderator | 4668
+
0
-

The only “correct” way to achieve this is to create all components from the place, where you have all the services, from the DI Container. It creates class hierarchies, so it makes sense.

I don't know about you, but I don't want my DIC to get bloated with all components and their creation. So we can solve this, little less cleanly, by creating them in presenter.

protected function createComponentMenu()
{
	$a = new ComponentA($this->container->serviceA);
	$a['b'] = new ComponentB($this->container->serviceB);
	$a['c'] = new ComponentC($this->container->serviceC);
	$a['c']['d'] = new ComponentD($this->container->serviceD);
	return $a;
}

When you have your components as separate classes, this shouldn't be a problem. Obviously, this creates space for builders and factories :)

Last edited by HosipLan (2011-10-09 19:56)

Nox
Member | 378
+
0
-

Thanks for response

This indeed should result in much cleaner classes, i like it!

There is perhaps a downside with less ability for lazy loading (only parent is lazy loader, children eagerly), but everything has a cost and if there's noticable performance issue in a specific case it could be reworked

Last edited by Nox (2011-10-09 21:14)