I am supporting multiple databases without using ORM tools. For this example I will show an example for Postgres and MSSQL UserQueries
I have an interface IDataBase
with multiple databases implementing this interface.
@injectable()
export class MssqlDatabase implements IDatabase {
public async connect(): Promise<void> {
}
public async disconnect(): Promise<void> {
}
}
Further I have my IUserQueries
interface defining the queries
export interface IUserQueries {
fetchUsers(): Promise<QueryResult>;
}
QueryResult
is a custom class to make sure, every database query returns the same data object for my API. My API calls the specific query from the target interface. If mssql
is the identifier in the config file, my application should create a connection to the MSSQL database. But my API files shouldn't care and don't know this (obviously, that's what a interface does).
A basic example would be
@injectable()
export class UserRepository implements IUserRepository {
public userQueries: IUserQueries;
constructor(@inject(IoCTypes.IUserQueries) userQueries: IUserQueries) {
this.userQueries = userQueries;
}
}
Now things get tricky here. My DI container:
const container: Container = new Container();
container.bind<IUserQueries>(IoCTypes.IUserQueries).to(/* what? */);
export { container };
The DI container doesn't know which query file to pick. It could be the MSSQLUserQueries
or PostgresUserQueries
. How can I solve this problem? It is possible to select the right queries when starting the server (app.ts) but as far as I understood, this DI container is completely independent from the application and just acts as a config file so I shouldn't pass in an abstract UserQueries
class.