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
Currently when defining arguments using injected, one has to pass in the constructor as a first argument. This kinda removes a lot of the flexibility a DI container can give you. Let's say we want to do the following:
constTOKENS={readCredentials: token<string>("readCredentials"),writeCredentials: token<string>("writeCredentials"),readConnection: token<DatabaseConnection>("readConnection"),writeConnection: token<DatabaseConnection>("writeConnection"),listTodosUseCase: token<ListTodosUseCase>("listTodosUseCase"),saveTodoUseCase: token<SaveTodoUseCase>("saveTodoUseCase"),};classDatabaseConnection{constructor(privatecredentials: string){}}classListTodosUseCase{constructor(privateconnection: DatabaseConnection){}}classSaveTodoUseCase{constructor(privateconnection: DatabaseConnection){}}container.bind(TOKENS.readCredentials).toConstant(config.db.credentials.read);container.bind(TOKENS.writeCredentials).toConstant(config.db.credentials.write);container.bind(TOKENS.readConnection).toInstance(DatabaseConnection);container.bind(TOKENS.writeConnection).toInstance(DatabaseConnection);/** * Perfect so far, we can give the different use cases the appropriate connections. */injected(ListTodosUseCase,TOKENS.readConnection);injected(SaveTodoUseCase,TOKENS.writeConnection);/** * Here we run into an issue, we can't inject different connection strings into the same constructor. */injected(DatabaseConnection,TOKENS.readCredentials);injected(DatabaseConnection,TOKENS.writeCredentials);
You could say well, just create a read and write connection class and let them implement the same interface. But this defeats the purpose. The implementation of these classes will be the same, resulting in code duplication.
A great thing about some DI containers is that they give you flexibility to have the same class with different arguments injected, registered under different keys. (that's why the injected function should probably also not be in the same file as the class definition, this removes that flexibility).
I first thought conditional bindings with tags would solve this, but they are also bound directly to the constructor. That just moves the issue one level up.
My proposed solution is as follows, let's define the injected arguments per token instead of per constructor:
Thanks for the suggestion, this is a very interesting thing. I have understood the problem and will think about how to solve it.
You said "A great thing about some DI containers is that they give you flexibility to…", it would be interesting to look at the implementation in other libraries, possibly in other languages.
Thanks for the suggestion, this is a very interesting thing. I have understood the problem and will think about how to solve it.
You said "A great thing about some DI containers is that they give you flexibility to…", it would be interesting to look at the implementation in other libraries, possibly in other languages.
Currently when defining arguments using
injected
, one has to pass in the constructor as a first argument. This kinda removes a lot of the flexibility a DI container can give you. Let's say we want to do the following:You could say well, just create a read and write connection class and let them implement the same interface. But this defeats the purpose. The implementation of these classes will be the same, resulting in code duplication.
A great thing about some DI containers is that they give you flexibility to have the same class with different arguments injected, registered under different keys. (that's why the
injected
function should probably also not be in the same file as the class definition, this removes that flexibility).I first thought conditional bindings with tags would solve this, but they are also bound directly to the constructor. That just moves the issue one level up.
My proposed solution is as follows, let's define the injected arguments per token instead of per constructor:
I can imagine, having the injected function as a separate function is then not even necessary anymore. We could do something like:
I think this would greatly improve the flexibility of this library. Let me know what you think!
The text was updated successfully, but these errors were encountered: