Jcorretjer
Jcorretjer

Reputation: 497

Should I inject every and any class or specific classes?

I just started getting into DI(dependency injection) frameworks and I was wondering should I inject every and any class or specific classes? How would I know which classes you should inject and which you shouldn't?

A lot of the tutorials(Dagger 2, Hilt, etc) that I've found don't seem to talk about this or don't explain it very well.

I don't have any code examples cause I'm trying out things as I read along with tutorials. Just trying to get a feeling of things.

Explain it as if I was 4 year old :)

Upvotes: 2

Views: 2586

Answers (2)

Nicolas
Nicolas

Reputation: 7081

There's a certain number of classes which I always inject and never ask myself the question: the application context, shared preferences, DAOs, Retrofit, Json object. As you can see, these are usually related the third-party libraries or the Android framework.

Then there are classes which depend on those: the repository is a common example, but there are many more. For example you could have a preference manager which depends on shared preferences and context. Or you could have a class JsonExporter used to export user data which depends on DAOs and the Json mapper.

In turn, there are other classes which depend on those new classes: a view model/presenter in MVVM/MVP architecture could depend on both the repository and JsonExporter for example. At this point you have two choices:

  1. Instantiate the class yourself. But that means you need to have access to all of the class' dependencies, which are only available through dependency injection...
  2. so you might as well inject it. The cost of injection at this point is often very low, just adding @Inject to the constructor. Only the base dependencies have to be provided in a module.

From a certain number of injected base classes, the decision to inject those more nested in the dependency graph really comes automatically.

There are also cases where you'll have a class that depends on nothing. Perhaps you decided to extract code from a big class into another one. Or perhaps the class just has no dependencies. I probably wouldn't inject such a class, there's no point.

Singletons are often handy to inject because the dependency injection framework (e.g. Dagger) can make sure there's always only one instance automatically.

One reason why we do dependency injection is so that classes depend on abstractions, not concretions (aka inversion of control). It's useful to have your class depend on a Repository interface, because you can decide to provide it with the implementation you want, for example RealRepository in the app, and MockRepository in tests. Another example is flavors or build variants: an injected FlavorBehavior interface could have different implementations in two different flavors. It's not the class' responsability to decide which to use.

Note that this is not a definitive answer, and I'm not an expert on the subject. It's an opinion-based subject too.

Upvotes: 0

oziomajnr
oziomajnr

Reputation: 1741

My answer is no, you do not have to do that use dependency injection every time you need to create an object.

This is the intent of dependency injection according to Wikipedia

The intent behind dependency injection is to achieve separation of concerns of construction and use of objects. This can increase readability and code reuse.

So you should use dependency injection it would improve your code reuse and readability.

This article mentions some cases where you should use dependency injection to create objects

  1. You need to inject configuration data into one or more components.
  2. You need to inject the same dependency into multiple components.
  3. You need to inject different implementations of the same dependency.
  4. You need to inject the same implementation in different configurations.
  5. You need some of the services provided by the container.

Imagine that you have username and password fields in an app that you would use to capture a user's detail, you do not have to use dependency injection to create a User object from the details, you can just create it directly, its not something that would be reused across your application, there are other object creation patterns that you should look into like factory pattern, abstract factory pattern, builder pattern e.t.c.

Upvotes: 2

Related Questions