@universal-di/core
v0.0.7
Published
Universal Dependency Injection for Typescript with Angular-like API
Downloads
10
Maintainers
Readme
Universal Dependency Injection
Contents
Providing Dependencies
Imagine there is a class called ProductService that needs to act as a dependency in a state.
The first step is to add the @Injectable decorator to show that the class can be injected.
@Injectable()
class ProductState {
}
@Injectable()
class ProductService {
}
Second step is to make it part of your module
@Module({
providers: [
ProductState,
ProductService
],
})
class ProductModule {
}
The last third step is to bootstrap a DIApplication
with your module
const app = new DIApplication(ProductModule);
Once you register a provider, you will get singleton instance of this service every time you'd try to inject it.
Injecting a Dependency
Registered provider can be injected into a class from the same @Module
@Injectable()
class ProductState {
constructor(private productService: ProductService) {
}
}
or directly from the bootstrapped module
const productState = app.rootInjector.get(ProductState);
Besides being a singleton, class is instantiated only when injected, not before.
Ports
In order to make working with universal-di easier (e.g. injecting dependencies), you can take advantage of ports for particular libraries:
- React @universal-di/react
Advanced usage
Imagine you are tracking events differently depending on environment
interface AnalyticsService {
track(event: string): void;
}
const ANALYTICS_SERVICE = new InjectionToken<AnalyticsService>('ANALYTICS_SERVICE')
After defining the abstraction, next step will be to define implementations
@Injectable()
class RealAnalyticsService implements AnalyticsService {
constructor(
@Inject(TRACKING_API_URL) private readonly _trackingApiUrl: string,
private readonly _httpClient: HttpClient,
) {
}
track(event: string): void {
this._httpClient.post<void>(this._trackingApiUrl);
}
}
@Injectable()
class ConsoleAnalyticsService implements AnalyticsService {
track(event: string): void {
console.log('[tracking]', event);
}
}
Put together in a @Module
const TRACKING_API_URL = new InjectionToken<string>('TRACKING_API_URL');
@Module({
providers: [
{
provide: ANALYTICS_SERVICE,
useClass: isDev() ? ConsoleAnalyticsService : RealAnalyticsService,
},
{
provide: TRACKING_API_URL,
useValue: '/api/track',
}
],
})
class AnalyticsModule {
}
@Module({
imports: [
AnalyticsModule,
],
providers: [
HttpClient,
]
})
class AppModule {
}
And use
const application = new DIApplication(AppModule);
// AnalyticsService type is inferred here
const analyticsService = application.rootInjector.get(ANALYTICS_SERVICE);
analyticsService.track('application-started');