@universal-di/core
TypeScript icon, indicating that this package has built-in type declarations

0.0.7 • Public • Published

Universal Dependency Injection

MIT License Build Status NPM version Coverage Status PRs welcome

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:

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');

Authors

szymeo bartoszswitalski

Package Sidebar

Install

npm i @universal-di/core

Weekly Downloads

0

Version

0.0.7

License

MIT

Unpacked Size

47.9 kB

Total Files

104

Last publish

Collaborators

  • sgracki