Nestjs wrapping external module in forRootAsync and inject instance

2.9k views Asked by At

I've been developing a wrapper module for nestjs based on a nodejs module. I created a static forRoot method in order to get the configuration. I created such a prodiver within the forRoot method:

const MyProvider = {
  provide: PROVIDER_TOKEN,
  useValue: new MyClass(options),
};

I also export it, so in consumer module it's easy to inject it in order to access to all methods of nodejs module. Besides, I am able to wrap up all methods of that module into my service methods. So, the following code give me access to the main module's instance:

constructor(@Inject(PROVIDER_TOKEN) private readonly myClass: MyClass) {}

Then I decided to create a forRootAsync method that can handle getting configuration with useFactory. Now this is my provider in forRootAsync method:

const MyProvider= {
  provide: PROVIDER_TOKEN,
  useFactory: optionsAsync.useFactory,
  inject: optionsAsync.inject || []
};

But this time if I inject PROVIDER_TOKEN to the service, this is simply the configuration object (that I pass from the consumer module). So I guess I should create the instance within constructor. Maybe something like this:

constructor(@Inject(PROVIDER_TOKEN) private readonly myClass) {
  if(!this.myClass typeof MyClass) {
    this.myClass = new MyClass(this.myClass);
  }
}

By this, I can't access the instance of the main module in the consumer modules by injecting PROVIDER_TOKEN token. The goal is to access all methods of that module without having to wrap all the methods up. Any idea?

1

There are 1 answers

0
Vahid Najafi On BEST ANSWER

We should handle this with two providers. In the first one, we pass the factory provider as following:

{
  provide: HTTP_MODULE_OPTIONS,
  useFactory: options.useFactory,
  inject: options.inject || [],
};

Then we create another provider which injects the first provider (which nestjs resolve the dependency at that point):

{
  provide: AXIOS_INSTANCE_TOKEN,
  useFactory: (config: HttpModuleOptions) => Axios.create(config),
  inject: [HTTP_MODULE_OPTIONS],
},

Here is the example.