0

I have this working example of injecting providers into my object, but I would like to know if there is a better way to solve this, than to use the Factory class below. Or do you avoid situations like this somehow completely? Is this even in-line with how dependency-injection is supposed to work?

See this gist https://gist.github.com/sezanzeb/4cca6f0e7689d75b5a1ec546c471c430 for the code sample.

I have searched a lot through StackOverflow and the NestJs examples, but couldn't find relevant answers. Only something similar in Angular.

sezanzeb
  • 816
  • 8
  • 20

1 Answers1

0

There are no NestJs (Or Angular) specific guidelines or best practices for this, as far as I can tell. This question needs to be answered by looking at the idea of dependency injection as a pattern.

Dependency Injection seems to be more about separating the instatiation of objects from where they are needed.

https://en.wikipedia.org/wiki/Dependency_injection

A basic benefit of dependency injection is decreased coupling between classes and their dependencies.

By removing a client's knowledge of how its dependencies are implemented, programs become more reusable, testable and maintainable.

This also results in increased flexibility: a client may act on anything that supports the intrinsic interface the client expects.

Using a factory, like proposed in the gist in the original question, fulfills all those criteria. There is, as far as I can tell, no built in way for NestJs to do such a thing, but it is easy to just create your own factory and inject that into your service.

Factories and DI are related: Dependency Injection vs Factory Pattern

"The DI pattern does not require any frameworks. You can do DI by manually writing factories which do DI. DI frameworks just make it easier"

"Factory pattern can be called as a tool to implement DI."

"Instead of instantiating the parts itself a car asks for the parts it needs to function."

static class CarFactory
{
    public ICar BuildCar()
    {
        Engine engine = new Engine();
        SteeringWheel steeringWheel = new SteeringWheel();
        Tires tires = new Tires();
        ICar car = new RaceCar(engine, steeringWheel, tires);
        return car;
    }
}

So to conclude, yes, I would consider the proposal in the gist as best practice for this matter:

@Injectable()
class HeroFactory {
    constructor(private readonly environmentService: EnvironmentService) { }

    public createWizard(name: string): Wizard {
        return new Wizard(name, 1, this.environmentService);
    }
}
sezanzeb
  • 816
  • 8
  • 20