Page Contents

Artifacts usually work together to implement the business logic. For example, GreetingService depends on greeters for different languages, such as EnglishGreeter and ChineseGreeter.

Common techniques of composition include hard coding the dependencies or locating the dependent artifacts. For example:

  1. Hard code dependencies and explicitly instantiate them

    import {EnglishGreeter, ChineseGreeter} from './greeters';
    export class GreetingService {
      private chineseGreeter: ChineseGreeter;
      private englishGreeter: EnglishGreeter;
      constructor() {
        this.chineseGreeter = new ChineseGreeter();
        this.englishGreeter = new EnglishGreeter();
      }
    }
    
  2. Use ServiceLocator pattern

    import {Context} from '@loopback/core';
    import {EnglishGreeter, ChineseGreeter} from './greeters';
    export class GreetingService {
      private chineseGreeter: ChineseGreeter;
      private englishGreeter: EnglishGreeter;
      constructor(context: Context) {
        this.chineseGreeter = context.getSync<ChineseGreeter>(
          'greeters.ChineseGreeter',
        );
        this.englishGreeter = context.getSync<EnglishGreeter>(
          'greeters.EnglishGreeter',
        );
      }
    }
    
  3. Use dependency injection

    Dependency Injection is a technique where the construction of dependencies of a class or function is separated from its behavior, in order to keep the code loosely coupled.

    This technique is being used commonly within the LoopBack framework.

    import {inject} from '@loopback/core';
    import {LifeCycleObserver} from '@loopback/core';
    import {CachingService} from '../caching-service';
    import {CACHING_SERVICE} from '../keys';
    export class CacheObserver implements LifeCycleObserver {
      constructor(
        @inject(CACHING_SERVICE) private cachingService: CachingService,
      ) {}
    }
    
    @injectable(asGlobalInterceptor('caching'))
    export class CachingInterceptor implements Provider<Interceptor> {
      constructor(
        @inject(CACHING_SERVICE) private cachingService: CachingService,
      ) {}
      value() {
        return async (
          ctx: InvocationContext,
          next: () => ValueOrPromise<InvocationResult>,
        ) => {
          // ...
        };
      }
    }
    

Types of dependency injections

There are 3 types of dependency injections:

  • Constructor injection
  • Property injection
  • Method injection

For more details, see the dependency injection page.


Previous: Part 3 - Manage artifacts

Next: Part 5 - Extension point and extension