Another way we can approach this is by taking advantage of the DI pattern. We're already familiar with it from AngularJS; let's demonstrate how we can refactor the preceding code using DI in the context of Angular:
class Engine {...} class Transmission {...} @Injectable() class Car { engine; transmission; constructor(engine: Engine, transmission: Transmission) { this.engine = engine; this.transmission = transmission; } }
All we did in the preceding snippet was add the @Injectable
class decorator on top of the definition of the Car
class and provide type annotations for the parameters of its constructor.
There is one more step left, which we'll take a look at in the next section. Before that, let's take a look at what the benefits of the mentioned approach are:
Car
class for a testing environment, or for instantiating different Car
models.The Car
class is only responsible for implementing its own domain-specific logic instead of being coupled with additional functionalities, such as the management of its dependencies. Our code also got more declarative and easier to read.
Now, that we've realized some of the benefits of DI, let's take a look at the missing pieces in order to make this code work.