Skip to content

Provider ​

Provider là khái niệm cơ bản trong hệ thống tiêm phụ thuộc của Orbit. Service, repository, factory và helper đều có thể là provider.

Service cơ bản ​

typescript
import { Injectable } from '@galaxy-stack/orbit-core';

@Injectable()
export class UserService {
  private users: User[] = [];

  findAll(): User[] {
    return this.users;
  }

  findOne(id: string): User | undefined {
    return this.users.find(u => u.id === id);
  }

  create(data: CreateUserDto): User {
    const user = { id: crypto.randomUUID(), ...data };
    this.users.push(user);
    return user;
  }
}

Kiểu Provider ​

Class Provider ​

typescript
@Module({
  providers: [UserService], // Viết tắt
})
export class UserModule {}

// Tương đương với:
@Module({
  providers: [
    {
      provide: UserService,
      useClass: UserService,
    },
  ],
})
export class UserModule {}

Value Provider ​

typescript
@Module({
  providers: [
    {
      provide: 'CONFIG',
      useValue: {
        apiUrl: 'https://api.example.com',
        timeout: 5000,
      },
    },
  ],
})
export class AppModule {}

Factory Provider ​

typescript
@Module({
  providers: [
    {
      provide: 'DATABASE_CONNECTION',
      useFactory: async (config: ConfigService) => {
        return await createConnection(config.get('DATABASE_URL'));
      },
      inject: [ConfigService],
    },
  ],
})
export class DatabaseModule {}

Provider hiện có (Alias) ​

typescript
@Module({
  providers: [
    UserService,
    {
      provide: 'AliasedUserService',
      useExisting: UserService,
    },
  ],
})
export class UserModule {}

Phạm vi tiêm ​

Singleton (Mặc định) ​

Một instance được chia sẻ trên toàn ứng dụng:

typescript
@Injectable()
export class ConfigService {}

Phạm vi Yêu cầu ​

Instance mới cho mỗi yêu cầu:

typescript
@Injectable({ scope: Scope.REQUEST })
export class RequestContextService {
  constructor(@Inject(REQUEST) private request: Request) {}
}

Phạm vi Tạm thời ​

Instance mới mỗi lần được tiêm:

typescript
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService {}

Phụ thuộc tùy chọn ​

typescript
@Injectable()
export class UserService {
  constructor(
    @Optional() private logger?: LoggerService
  ) {}
}

Token tiêm tùy chỉnh ​

typescript
// tokens.ts
export const DATABASE_CONNECTION = Symbol('DATABASE_CONNECTION');

// module.ts
@Module({
  providers: [
    {
      provide: DATABASE_CONNECTION,
      useFactory: () => createConnection(),
    },
  ],
})
export class DatabaseModule {}

// service.ts
@Injectable()
export class UserRepository {
  constructor(
    @Inject(DATABASE_CONNECTION) private db: Connection
  ) {}
}

Phụ thuộc vòng tròn ​

Sử dụng forwardRef() để xử lý phụ thuộc vòng tròn:

typescript
@Injectable()
export class UserService {
  constructor(
    @Inject(forwardRef(() => PostService))
    private postService: PostService
  ) {}
}

Released under the MIT License.