You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Following some comments here on how to pass arguments to constructors on top of the injected properties, I'm using Token to do it as mentonned.
In my case, my class is extending another one, so I need to pass an argument to the child class to then bypass it tp the parent one (super(value)). For the example, I have added 2 args, but they could be more in the real program. That is why I also want to avoid using mixins, which could be a solution to avoid args in the class.
The solution I have with Token is working well.
However there is a "leak" of type safety when it comes to generics in Token.
Please check the example below. This is a simple DI Pattern for Repository. I have created a 'contract' with the Interface, and then created an implementation to this interface.
The implementation needs a DB_CONNECTION to simulate the connection to a real DB.
It needs also other properties, espacially one to be send to its parent class. They are defined in the generic type TClassParams
But I have to type the token related to this params as Token<any,any> which might create an issue when settings the values in the container. For example, the "value:U" field in the TClassParam type finaly is expecting a number, but I can pass a string or anything else.
Is there a way to do it better ? The initial requirement is to pass additionnal parameters in the constructor of the class that receive injection.
Thks
import "reflect-metadata";
import { Container, Inject, Service, Token } from "typedi";
// for better DI management, I'm using interfaces as "contract"
interface IInterfaceRepo<TDataType extends Record<string, any>> {
list(): Array<TDataType>;
findOne<K extends keyof TDataType>(key: K, value: TDataType[K]): TDataType | undefined;
}
// type of the parameters of the first implementation of my interface
type TClassParams<T, U> = {
initialData: Array<T>;
value: U;
};
// data types manage by the repository
type TData = { a: string; b: boolean };
// the parent class I want to extends. Doesn't need injected values
class CParent<T> {
constructor(private value: T) {}
showMeValeur() {
return this.value;
}
}
// creation of the tokens. One for the DB_CONNECTION and the other one for additional params
const DB_CONNECTION = new Token<string>("DB_CONNECTION");
const CLASS_PARAMS = new Token<TClassParams<any, any>>("CLASS_PARAMS"); //<--- note the ANY, ANY here. Type safty is lost
// the first implementation of the class
@Service()
class RepoImpl<T extends Record<string, any>, U = number> extends CParent<U> implements IInterfaceRepo<T> {
private _data: T[];
constructor(
// injection of the DB_CONNECTION and additional params
@Inject(DB_CONNECTION) private readonly _dbConnection: string,
@Inject(CLASS_PARAMS) readonly _classParams: TClassParams<T, U>
) {
super(_classParams.value); //<-- for example, on of the params is sent to the parent class
this._data = _classParams.initialData;
}
list(): T[] {
return this._data;
}
findOne<K extends keyof T>(key: K, value: T[K]): T | undefined {
return this._data.find((d) => (d[key] = value));
}
showMeProperties() {
console.log(this._data, " -- ", this._dbConnection, " *** ", this.showMeValeur());
}
}
const initialData: TData[] = [
{
a: "hi",
b: false,
},
];
Container.set(DB_CONNECTION, "connectio container");
Container.set(CLASS_PARAMS, {
initialData: initialData,
value: 4, <-- I can set a string or boolean here. As a result, program will crash at runtime
});
const repo = Container.get<RepoImpl<TData>>(RepoImpl<TData>);
console.log("list ", repo.list());
repo.showMeProperties();
The text was updated successfully, but these errors were encountered:
Following some comments here on how to pass arguments to constructors on top of the injected properties, I'm using Token to do it as mentonned.
In my case, my class is extending another one, so I need to pass an argument to the child class to then bypass it tp the parent one (
super(value)
). For the example, I have added 2 args, but they could be more in the real program. That is why I also want to avoid usingmixins
, which could be a solution to avoid args in the class.The solution I have with
Token
is working well.However there is a "leak" of type safety when it comes to generics in
Token
.Please check the example below. This is a simple DI Pattern for Repository. I have created a 'contract' with the Interface, and then created an implementation to this interface.
The implementation needs a
DB_CONNECTION
to simulate the connection to a real DB.It needs also other properties, espacially one to be send to its parent class. They are defined in the generic type
TClassParams
But I have to type the token related to this params as
Token<any,any>
which might create an issue when settings the values in the container. For example, the "value:U
" field in theTClassParam
type finaly is expecting anumber
, but I can pass a string or anything else.Is there a way to do it better ? The initial requirement is to pass additionnal parameters in the constructor of the class that receive injection.
Thks
The text was updated successfully, but these errors were encountered: