DI Flashcards
On-demand approach
In the on- demand approach, whenever a consumer needs a new object-under-construction, the consumer creates or finds the dependencies needed by the object-under-constructionat the time the consumer instantiates the object-under-construction. In other words, the consumer is responsible for gathering all dependencies and is responsible for providing those dependencies to the object-under-construction via the initializer, a stored- property or a method.
What are ephemeral dependencies?
they’re created and destroyed alongside the object-under-construction.
dependencies that can be instantiated at the same time as the object-under-construction
On-demand approach, Initializing ephemeral dependencies
If dependencies don’t need to live longer than the object-under-construction, and can therefore be owned by the object-under-construction, then
the consumer can simply initialize the dependencies and provide those dependencies to the object-under- construction. These dependencies are ephemeral dependencies because they’re created and destroyed alongside the object-under-construction.
Initializing ephemeral dependencies On-demand approach
Consumer know that concrete implementation of dependencies for object-under-construction.
object-under-construction doesn’t know it, because it uses protocol types for dependencies
Pros of the on-demand approach
This approach is relatively easy to explain and relatively easy to understand.
Your code is testable because you can substitute nondeterministic side effect dependencies with deterministic fake implementations.
You can defer decisions. For example, you can use an in-memory data store implementation while you decide on a database technology. Changing from the in- memory implementation to the database implementation is easy because you can find all the in-memory instantiations and replace them with the database instantiations. This can be a bit tedious, so this is also a con that’s addressed in more advanced approaches.
• Your team can work on the same feature at the same time because one developer can build an object-under-construction while another builds the dependencies. The developer building the object-under-construction can use fake implementations of the dependencies while the other developer builds the real implementations of the dependencies.
Cons of the on-demand approach
Dependency instantiations are decentralized. The same initialization logic can be duplicated many times.
Consumers need to know how to build the entire dependency graph for an object- under-construction. Dependencies can also have dependencies and so on. The consumer might have to instantiate a lot of dependencies. This is not ideal because multiple consumers using the same object-under-construction class will have to duplicate the dependency graph instantiation logic.
Instantiating dependencies on-demand is a decentralized approach that
doesn’t scale well.
The factories approach is all about centralizing
dependency instantiation.
One goal of creating a factories class is to make it possible
for consumers to create objects-under-construction without having to know how to build dependency graphs required to instantiate objects-under-construction.
Creating and getting transitive dependencies
To create an ephemeral transitive dependency, a dependency factory method can simply call another dependency factory included in the factories class.
To get a reference to a long-lived transitive dependency, a dependency factory method should
include a parameter for the transitive dependency. By adding parameters, long-lived transitive dependencies can be provided to the dependency factory method.
Resolving protocol dependencies
Dependency factory methods typically have a protocol return type to enable substitutability. When this is true, dependency factory methods encapsulate the mapping between protocol and concrete types. This is typically called resolution because a dependency factory method is resolving which implementation to create for a particular protocol dependency. In other words, these methods know which concrete initializer to use.
Object-under-construction factory methods
Object-under- construction factory methods look just like dependency factory methods. The only difference is
object-under-construction factory methods are called from the outside of a factories class, whereas dependency factory methods are called within a factories class.
Getting runtime values factory approach
These runtime values are typically called runtime factory arguments. As the name suggests, you handle this situation by adding a parameter, for each runtime value, to the object-under-construction’s or dependency’s factory method. At runtime, the factory method caller will need to provide the required values as arguments.
Injecting factories goal
The goal is to be able to unit test an object-under-construction without needing the factories class at all.
You can give this power to objects-under-construction from the outside using one of two Swift features:
closures or protocols.