I am trying to create a new instance without breaking the DI layer, allowing my instance to have access to all injectable services it is using in its constructor
n example of what I have currently which does not allow me using any injectable services:
const camera: Camera = new Camera(id, options);
With this approach, the camera class could not import any injectable singletons or classes.
I have read here that you can use moduleRef
to create a new instance, so I tried the following:
const camera: Camera = await this.moduleRef.create(Camera);
But the issue now is, I can't pass the ID
and Options
parameters, the only solution would be using a setter right after initializing it.
Question:
How can you create a new instance (not singleton) of a class, have it created by nest's injector and pass custom parameters on creation in the latest version of NestJS?
Dependency injection is an inversion of control (IoC) technique wherein you delegate instantiation of dependencies to the IoC container (in our case, the NestJS runtime system), instead of doing it in your own code imperatively.
@Injectable() is how you tell Nest this is a class that can have dependencies that should be instantiated by Nest and its DI system. The code you posted works because there are no injected dependencies.
NestJS Modules are Singletons by default. Their Providers are also singletons when they are provided from within the same module. However, there are cases where we want to use just a single solo class as a provider to a couple or more modules.
To instruct Nestjs that we need the body values from the request, we should use the @Body() decorator function from the @nestjs/common module before the body parameter. Doing this will bind the body values from the request to the body parameter in the createPost() method.
Custom provider is what you need, you can find documentation here
If you want inject it in some of your modules try this way
@Module({
...
providers: [
{
useFactory: (optProvider) => {
return new Camera(optProvider.id, optProvider.options);
},
provide: Camera,
import: [OptProvider] // pay attention that OptProvider is a valid provider in this module
},
SomeService
]
})
export class SomeModule {}
After it you can use provide this object via DI
export class SomeService() {
constructor( protected readonly camera: Camera ) {}
}
We had the same issue. The way we solved it is by using the useFactory, and instead of returning the value, we retuned a factory function that excepts the extra arguments and we use it to create new instances. Like so:
const factory = {
provide: PUPPETEER_FACTORY,
useFactory: (configService): PuppeteerFactory => {
return {
create: function(config?: PuppeteerConfig) {
return new Puppeteer(configService, config);
}
};
},
inject: [ConfigService]
};
and than you simply use the create function that is returned, like so:
constructor(@Inject(PUPPETEER_FACTORY) private puppeteerFactory: PuppeteerFactory) {}
this.puppeteerInstance = this.puppeteerFactory.create({
timezone: "UTC+8",
userAgent: "BLA"
});
Notice that PUPPETEER_FACTORY is a const
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With