Гайды / Работа с DI 
В этом разделе описано, как интегрировать Nuxoblivius с контейнерами зависимостей (DI). Для примера мы будем использовать популярный контейнер Inversify.
1. Подготовка 
Перед началом работы с Nuxoblivius и интеграцией с DI необходимо выполнить базовую настройку проекта.
Установите зависимости
npm install nuxoblivius inversifyИнициализация контейнера
import { Container } from "inversify";
const container = new Container();2. Создание UserService 
Создадим сервис, который будет хранить и управлять данными пользователя. Он будет зарегистрирован как singleton, чтобы одно состояние переиспользовалось во всём приложении.
import { subStore } from "nuxoblivius";
interface IUser {
  id: number;
  name: string;
}
export class UserService {
  private user?: IUser;
  public setUser(user: IUser): void {
    this.user = user;
  }
  public getUser(): IUser {
    if (!this.user) {
      throw new Error("User is empty");
    }
    return this.user;
  }
  public isLoggedIn(): boolean {
    return this.user !== null;
  }
}
export const useUserService = () => subStore(UserService);import { defineFactory } from "nuxoblivius";
interface IUser {
  id: number;
  name: string;
}
export class UserService {
  private user?: IUser;
  public setUser(user: IUser): void {
    this.user = user;
  }
  public getUser(): IUser {
    if (!this.user) {
      throw new Error("User is empty");
    }
    return this.user;
  }
  public isLoggedIn(): boolean {
    return this.user !== null;
  }
}
export const useUserService = defineFactory(UserService);3. Регистрация UserService 
Добавляем UserService в DI-контейнер:
import { Container } from "inversify";
import { UserService, useUserService } from "@/service/UserService";
export const container = new Container();
container
  .bind(UserService)
  .toDynamicValue(() => useUserService())
  .inSingletonScope();4. Внедрение зависимостей 
После регистрации сервисов и стора в контейнере, их можно внедрять (инъектировать) в другие классы.
import { subStore, Record } from "nuxoblivius";
import type { UserService } from "@/service/UserService";
export class PostService {
  private posts = Record.new("/api/posts", []);
  // Добавляем зависимость как аргумент
  constructor(private userService: UserService) {}
  async getUserPosts() {
    if (!this.userService.isLoggedIn()) {
      throw new Error("User is not loggined");
    }
    const user = this.userService.getUser();
    return await this.posts.query({ userId: user.id }).get();
  }
}
export const usePostService = (userSerivce: UserService) = subStore(PostService, userService);import { defineFactory, Record } from "nuxoblivius";
import type { UserService } from "@/service/UserService";
export class PostService {
  private posts = Record.new("/api/posts", []);
  // Добавляем зависимость как аргумент
  constructor(private userService: UserService) {}
  async getUserPosts() {
    if (!this.userService.isLoggedIn()) {
      throw new Error("User is not loggined");
    }
    const user = this.userService.getUser();
    return await this.posts.query({ userId: user.id }).get();
  }
}
export const usePostService = defineFactory(PostService);Так-же регистрация в контейнере:
import { Container } from "inversify";
import { UserService, useUserService } from "@/service/UserService";
import { PostService, usePostService } from "@/service/PostService";
export const container = new Container();
container
  .bind(UserService)
  .toDynamicValue(() => useUserService())
  .inSingletonScope();
container.
  .bind(PostService)
  .toDynamicValue(() => usePostService(
    // Подключаем зависимость
    container.get<UserService>(UserService)
  ))
  .inSingletonScope();5. Внедренние в Vue Файл 
Внедрение работает через контейнер, так-же как и в примерах выше.
<script setup lang="ts">
import { container } from "@/config/di";
import { PostService } from "@/service/PostService";
const postService = container.get<PostService>(PostService);
const userPosts = await postService.getUserPosts();
</script>
<template>
  {{ userPosts }}
</template>Итого 
Во фронтенде DI используют реже, чем в бэкенде, но он реально даёт плюсы, особенно если проект крупный и модульный. Вот основные плюсы:
Ослабленная связность (Loose Coupling)
Компоненты и сервисы не знают, кто именно создаёт их зависимости. Они просто описывают «мне нужен UserService», а контейнер уже решает, какую реализацию дать. Это снижает «спагетти-зависимости» в коде.
Лёгкое тестирование
С DI можно в контейнер подложить мок или фейковую реализацию.Например, вместо настоящего ApiService в тестах используется FakeApiService, и код компонента менять не нужно.
Гибкая замена реализаций
Если сервис меняется (например, LocalStorageAuthService -> JwtAuthService), то компоненты этого не замечают: достаточно переназначить биндинг в контейнере.
Управление жизненным циклом
DI позволяет контролировать:
- singleton (один на всё приложение),
 - transient (новый объект при каждом запросе),
 - scoped (на сессию, на страницу и т.д.). Это полезно для сторов, кэшей, сервисов пользователя.
 
Единый подход к управлению состоянием
DI-контейнер можно использовать как центральный реестр сервисов:
- UserService (данные пользователя)
 - ApiService (работа с запросами)
 - ThemeService (тема интерфейса)
 
Вместо глобальных переменных/хаков — всё под контролем.
Удобная интеграция в архитектуре (Clean/FSD/MVVM)
DI отлично ложится в архитектурные подходы:
- View → Store → Service → Record (API)
 
Компонент просто запрашивает Store/Service из контейнера и не думает, «как он создаётся».
В итоге:
- В маленьких проектах DI может быть избыточен.
 - В средних и больших фронтенд-проектах DI упрощает тестирование, модульность и рефакторинг.
 
