Введите несколько классов, которые используют выборку HttpClient в Aurelia

У меня есть класс под названием Инфраструктура, для которого я думал, что было бы удобно наследовать от HttpClient, Этот класс предоставляет методы для получения, публикации, размещения и удаления.

import {Aurelia} from "aurelia-framework";
import {HttpClient, json} from "aurelia-fetch-client";

export default class Infrastructure extends HttpClient {
    get(url, queryString, contentType) {
        //..
    }

    post(url, data, contentType) {
        //..
    }

    put(url, data, contentType) {
        //..
    }

    delete(url, contentType) {
        //..
    }
}

Идея в том, что теперь у меня могут быть услуги, которые вводят Infrastructure и они могут позвонить configure на инфраструктуру

import {inject} from "aurelia-framework";
import Infrastructure from "./infrastructure";

@inject(Infrastructure)
export class InventoryService {
    constructor (infrastructure) {

        infrastructure.configure(config => {
            config
                .useStandardConfiguration()
                .withBaseUrl(`http://localhost:64441/inventory`);
        });

        this.infrastructure = infrastructure;
    }
}

У меня есть пара сервисов, которые используют Infrastructure так и все работает нормально. Проблема в том, что мне не нужно вводить две такие службы в один и тот же класс, и настроенный baseUrl мешать друг другу.

Я понимаю, что в Аурелии все по умолчанию одно, но какой предпочтительный способ справиться с этой ситуацией в Аурелии?

Я знаю, что всегда могу пропустить настройку baseUrl, но это очень удобно, чтобы иметь возможность настроить, и мне любопытно, если есть лучший способ.

1 ответ

Решение

Вы можете зарегистрировать несколько экземпляров одного и того же "класса", используя разные ключи. Ключ регистрации может быть любым, он не должен быть функцией класса / конструктора.

Ниже приведен пример. Первый шаг - изменить свой Infrastructure класс для принятия аргумента baseUrl в конструкторе:

export class Infrastructure {
  constructor(baseUrl) {
    this.configure(config => {
      config
        .useStandardConfiguration()
        .withBaseUrl(baseUrl);
      });
  }
  ...
}

Далее вам нужно настроить контейнер с другими Infrastructure экземпляров. Код ниже, как правило, происходит при запуске, возможно, в main.js:

// configure the container
container.registerInstance("Inventory", new Infrastructure("http://foo.com"));
container.registerInstance("Orders", new Infrastructure("http://bar.com"));

Теперь вы сможете разрешить эти случаи по ключу:

// resolve by name
var inventory = container.get("Inventory");
var orders = container.get("Orders");

Или объявите их как зависимости, используя @inject:

import {inject} from "aurelia-framework";

@inject("Inventory", "Orders")
export class InventoryService {
  constructor (inventory, orders) {
    this.inventory = inventory;
    this.orders = orders;
  }
}

В этом выпуске много дискуссий о сценарии, очень похожем на ваш: https://github.com/aurelia/dependency-injection/issues/73

Другие вопросы по тегам