Dependencies Injection в Angular

Dec 29, 2018

Преимущества

Преимущества Dependencies Injection - создание зависимостей 'под капотом', гибкое управление зависимостями.

Основные концепции

  • Provider's - место, где мы описываем зависимости.
  • Injector - инструмент внутри Angular, который помогает разрешить зависимости и создать их.
  • Dependency's - зависимость, то есть непосредственно наш служебный класс (в большинстве случаях).

Регистрация провайдера с использованием

provider определяется объектом, в которому мы задаем два параметра:

  • ключ (token) - по которому определена зависимость
  • "рецепт", например, useClass - по которому Angular будет создавать наши зависимости.

Регестрируем зависимость через класс (useClass)

@Component({
    selector: "sample",
    templateUrl: "sample.component.html",
    providers: [{
        provide: Logger,   // token
        useClass: Logger   // "рецепт"
    },
    // если имя token и класса совпадает, то:
    Logger
    ]
})
export class SampleComponent {
    private message: string;

    constructor(private logger: Logger) { }
}

Регестрируем зависимость 'как переменную' через InjectionToken (используя useValue)

Допустим вместо класса есть переменная и мы хотим внедрять данную переменную как зависимость. Для данного случая есть InjectionToken:

import { InjectionToken } from '@angular/core';

const API_URL = new InjectionToken<string>('API_URL');  // 'API_URL' - имя ключа

@NgModule({
    providers: [{
        provide: API_URL, useValue: 'path_to_api.com' // 'path_to_api.com' - значение
    }]
})


// получаем в каком-то компоненте:

export class MyComponent {
    constructor(@Inject(API_URL) url) {
    
    }


Регестрируем зависимость через useFactory

useFactory используем в случае, когда мы хотим создать свой constructor и уже в нем определить как возвращать экземпляр Logger

@NgModule({
    providers: [{
        provide: Logger, useFactory: function() {

            // condition may be here
            return new Loger();
        } // ,deps: [LogService] - прописываем зависимости, если требуется
    }]
})

Регестрируем зависимость через useExisting

useExisting используем в случае, когда мы хотим использовать провайдер, который был определен до этого.

@NgModule({
    providers: [{
            provide: Logger, useClass: WorkService
        },
        {
            provide: Logger, useExisting: WorkService
        }
    ]
})

Injector

Мы можем получить Injector и работать с ним напрямую:

import { ReflectiveInjector } from '@angular/core';

// Angular v.>5 вместо ReflectiveInjector используется StaticInjector

// получаем injector
const injector: Injector = ReflectiveInjector.resolveAndCreate({
            provide: Logger, useClass: WorkService
        });

// resolveAndCreate - принимает описание всех наших зависимостей

// по token получаем нужную зависимость:
const loger = injector.get(Logger);

Декортатор @Injectable или использование сервиса внутри сервиса

Декортатор @Injectable делает служебные классы (сервисы) видимыми для механизма внедрения зависимостей.

import { Injectable } from '@angular/core';

@Injectable()
export default class MyService {
    constructor(myService: MyService) {
    }

provideIn

Свойство provideIn - определяет в каком модуль будет объявлен сервис. Это было сделано для оптимизации кода.

import { Injectable } from '@angular/core';

@Injectable({
    provideIn: 'root'    
})
export  class MyService {

Добавить комментарий
Комментарии:
Наталья
Mar 1, 2020
РегИстрируем! Исправьте, глаза режет