#Understanding dependency injection vs top level instantiation

1 messages · Page 1 of 1 (latest)

feral urchin
#

Currently in my company, people use a bigquery handler from a file bigquery.ts

import {query} from 'biquery.ts'
query.doSomeStuff(...)

In this bigquery.ts file I've got a top level:

const BQ = new BigQuery({
  credentials:...
  scopes: ...
});

export async function query<T>(
  query: string,
  params = {},
  labels = {}
): Promise<T[]> {
const [job] = await BQ.createQueryJob({
...
}

I have trouble understanding if this implementation would benefit to be in a BigQueryService to be used with DI, and why would it be seen as good practice?

  • Parameters of the BigQuery object don't change

Why having it as a dependency would be cleaner than doing a:
import {query} from 'biquery.ts'
Each time I need it?

latent nimbus
#

What you definitely should not do is create a new instantiation of BigQuery every time you need it, but instead, build a service out if its functionality. I'd even go so far as to say, it needs to be its own module, if this is Google's BigQuery client. Looks like someone started to do this too (if my assumption that this is Google's BigQuery client we are speaking about).
https://github.com/vlototskyi/nestjs-google-bigquery/tree/master

feral urchin
#

Thanks for your reply @latent nimbus , that's exactly what I did, a proper Google BigQuery module. But now I have to sell it to my team, and except "code will be easier to read", I don't see many arguments.
Apparently importing it without DI would still create a singleton out of it

dark spear
#

Parameters of the BigQuery object don't change
Is that right? Because credentials sounds like a variable. One that would be ideally provided from something that knows how to deal with such variables - a configService or so. Now you could definitely apply the same approach and have config.ts with export const config = new Config() and import the instance from there, but then what if Config needs another dependency to exist?

Then comes the question of mocking. You could mock the query function in tests of anything that you believe uses it, but wouldn't it be nicer to know for sure that a service depends on the query? Ideally, that you wouldn't even be able to construct such service without providing it, just to prevent having an instance in a weird state?

That's some of the issues DI is helping you with. If you need arguments for your team, I'd say go find some nice article about DI and take some arguments from there to help you.

What you shared will probably work just fine, it's just not "the clean code".

latent nimbus
#

Yeah, if your team has no understanding of what inversion of control is all about and why it is advantageous via a DI container, they need a lesson about those topics. Then the why of "why should it be a Nest module" becomes perfectly clear. 🙂