Simplest way to implement dependancy injection #4268
Replies: 3 comments 4 replies
-
Hi @RoyalVICTOR-pro! I'm working on a project with a similar structure, and I am applying a very close solution. In my case, I have: On repositories, I've created a base abstract class called RepositoryBase that implements a contract called IRepositoryBase. On services, a similar thing, for sample UserService implementing a contract called IUserService. User service class annotated with @Inject (adonis fold) and in the constructor are injected the IUserRepository contract:
In UserController annotated with @Inject, are injected IUserService contract:
Finally in AppProvider:
And, on method register, I have call these private methods:
And that's it, the dependency injection will replace my contracts injection on constructors by a concrete class that I defined on AppProvider |
Beta Was this translation helpful? Give feedback.
-
Hello everyone, I've been following this discussion here and wanted to share my recent experience with dependency injection in AdonisJS, specifically when injecting a custom UserRepository. I encountered two primary errors:
My breakthrough came when I used the UserService Injection: import UserRepository from 'App/Repositories/Interfaces/UserRepository/UserRepository';
@inject([UserRepository])
export default class UserService {
constructor(protected userRepository: UserRepository) {}
} Binding in Provider: public async register() {
this.app.container.singleton('App/Repositories/Interfaces/UserRepository/UserRepository', () => new FirebaseUserRepository())
} For controllers like UsersController, direct injection of UserService simplified things: import UserService from 'App/Services/UserService'
@inject()
export default class UsersController {
constructor(protected userService: UserService) {} I used an abstract class instead of an interface for UserRepository, as interfaces do not exist in JavaScript and are removed during transpilation: export default abstract class UserRepository {
abstract find(id: string): Promise<User | null>
abstract create(userData: Partial<User>): Promise<User>
abstract update(id: string, userData: Partial<User>): Promise<User | null>
abstract delete(id: string): Promise<void>
} Additionally, I have an idea that might further refine the implementation, though I'm still exploring its feasibility. I believe creating a contract to expose the dependency could streamline the process even more. This approach would involve defining a clear and explicit interface for our dependencies, potentially making the code cleaner and more maintainable. declare module '@ioc:App/Repositories/Interfaces/UserRepository/UserRepository' {
import UserRepository from "App/Repositories/Interfaces/UserRepository/UserRepository";
export default UserRepository
} I'm currently testing this approach and found a video that demonstrates the use of modules in a similar context, which could be quite enlightening:. This video provides practical insights into how such an implementation could be structured and integrated. While I'm still validating this concept in AdonisJS, I think it shows promise for further improving the architecture. I’d love to hear any insights or experiences from the community regarding the use of contracts in such scenarios I'm sharing this in the hope that it might help others facing similar challenges. I'm also interested in hearing any thoughts or further insights on using contracts in AdonisJS. |
Beta Was this translation helpful? Give feedback.
-
Hey there, when working on this, I usually go with something like: UsersController import { inject } from '@adonisjs/fold'
import SingletonService from 'App/Services/SingletonService'
import MultitonService from 'App/Services/MultitonService'
@inject()
class UsersController {
protected singletonService = SingletonService
constructor(protected multitonService: MultitonService) {}
} SingletonService class SingletonService {
// ...
}
export default new SingletonService() MultitonService class MultitonService {
// ...
}
export default MultitonService |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
After a lot of research and problems, I recently managed to implement dependency injection in an AdonisJS 5 project. I did this on a simple user creation feature.
In summary, in my n-tier architecture, I have a UserRepository that takes care of creating the user in the database.
My UserRepository is injected into an AuthService that will take care of the business logic.
My AuthService is injected into an AuthController that takes care of validating the elements retrieved in the request.
My AuthController, after the checks, calls the injected AuthService, which performs the business actions, and then calls the injected UserRepository for database creation.
I would like to know if there is a better, cleaner, or simpler way (because I find this to be quite heavy for what it does, and I am afraid of the complexity of the code when there will be many features). I am specifically referring to the part in AppProvider about dependency injection.
Here is the code I have implemented (I only give you what is useful):
start/routes.ts
app/Controllers/Http/AuthController.ts
app/Services/AuthService.ts
app/DataAccessLayer/Repositories/UserRepository.ts
providers/AppProvider.ts
Thank you for your advices !
Beta Was this translation helpful? Give feedback.
All reactions