Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependecy Injection: How To Overcome Cyclic Dependencies

Thanks for reading.

I'm using Unity framework to implement dependency injection in my app (ASP.Net MVC). Sometimes there are some cyclic dependencies among services that I want to avoid.

So I'm looking for solutions : )


My case

well lets imagine 3 services ServiceSally, ServiceJoe, ServiceJudy

ServiceSally depends on ServiceJoe

ServiceJoe depends on ServiceJudy

ServiceJudy depends on ServiceSally (<< That is kind of weird isn't it?)

So if you instance ServiceSally, she will need ServiceJoe to be injected, and ServiceJoe will need ServiceJudy and.... BANG!... ServiceJudy will need ServiceSally starting an endless cycle -and very sad love triangle-.


How could I solve this cyclic-loveTriangle case? : /

UPDATE:

My first solution: The LazyJoe

What about to use a wrapper around the services references to delay the injection until they are used?

What do you think?

like image 447
SDReyes Avatar asked Feb 13 '10 20:02

SDReyes


People also ask

How do you solve cyclic dependencies?

A cyclic dependency is an indication of a design or modeling problem in your software. Although you can construct your object graph by using property injection, you will ignore the root cause and add another problem: property injection causes Temporal Coupling. Instead, the solution is to look at the design closely.

How do you break cyclic dependency in spring?

A simple way to break the cycle is by telling Spring to initialize one of the beans lazily. So, instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.

Does constructor injection prevent circular dependencies?

Constructor Injection fails when there is Circular Dependency between spring beans. So in this case we Setter injection helps to resolve the issue. Basically, Constructor Injection is useful for Mandatory dependencies, for optional dependencies better to use Setter injection because we can do re-injection.


2 Answers

This depends on what (if any) DI framework you're using. Spring for example will handle this kind of cyclic dependency as long as not every involved bean (object) is initialized by a constructor. Basically it injects an empty object into (at least) one of the other beans and initializes it later. So the sequence is something like:

  1. Create a ServiceSally
  2. Create a ServiceJoe
  3. Create a ServiceJudy
  4. Initialize ServiceJudy
  5. Inject ServiceJudy into ServiceJoe
  6. Initialize ServiceJoe
  7. Inject ServiceJoe into ServiceSally
  8. Initialize ServiceSally
  9. Inject ServiceSally into ServiceJudy
  10. Tell ServiceJoe, ServiceJudy and ServiceSally that they're ready

This is why initialization-on-construction won't work with this method (because initialization is deferred). It's really the only way to handle it. Well maybe you could use some kind of proxy (temporary or permanent) too.

Generally speaking, at least in my experience, cyclic dependencies are symptomatic of a design that is either flawed in some way or in need of simplification.

like image 102
cletus Avatar answered Sep 28 '22 04:09

cletus


Don't make a Service* dependent on another concrete Service*. Make them dependent on a superclass or interface. Then inject a concrete Service* into another Service* after creation.

like image 22
Ozan Avatar answered Sep 28 '22 03:09

Ozan