Интеграция с DI
Aspid.MVVM поддерживает Zenject и VContainer для автоматического разрешения ViewModel через Dependency Injection.
Содержание
Обзор
Интеграция с DI позволяет:
- Разрешать ViewModel из DI-контейнера
- Инжектировать зависимости в ViewModel
- Использовать
ViewInitializerсInitializeStage.DiConstructor
Поддерживаются два DI-фреймворка:
- Zenject (Extenject)
- VContainer
Zenject
Шаг 1: Определите символ компиляции
В Project Settings → Player → Scripting Define Symbols добавьте:
ASPID_MVVM_ZENJECT_INTEGRATION
Шаг 2: Зарегистрируйте ViewModel в контейнере
using Zenject;
public class GameInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<PlayerViewModel>().AsSingle();
Container.Bind<InventoryViewModel>().AsSingle();
}
}
Шаг 3: Настройте ViewInitializer
- Добавьте
ViewInitializerна GameObject - Установите
InitializeStage→ DiConstructor - В секции ViewModel выберите
ResolveType→ Di - В
TypeSelectorукажите тип ViewModel (например,PlayerViewModel)
Zenject автоматически инжектирует контейнер в ViewInitializerBase через [Inject].
Пример ViewModel с Zenject
[ViewModel]
public partial class PlayerViewModel
{
[OneWayBind] private string _name;
[OneWayBind] private int _health;
private readonly IPlayerService _playerService;
// Zenject инжектирует IPlayerService автоматически
public PlayerViewModel(IPlayerService playerService)
{
_playerService = playerService;
_name = playerService.Name;
_health = playerService.Health;
}
}
VContainer
Шаг 1: Определите символ компиляции
ASPID_MVVM_VCONTAINER_INTEGRATION
Шаг 2: Зарегистрируйте ViewModel
using VContainer;
using VContainer.Unity;
public class GameLifetimeScope : LifetimeScope
{
protected override void Configure(IContainerBuilder builder)
{
builder.Register<PlayerViewModel>(Lifetime.Scoped);
builder.Register<InventoryViewModel>(Lifetime.Scoped);
}
}
Шаг 3: Настройте ViewInitializer
Аналогично Zenject — через Inspector с InitializeStage.DiConstructor.
DiConstructor
InitializeStage.DiConstructor — специальный этап, при котором:
- DI-контейнер инжектирует себя в
ViewInitializerBase - При инициализации
ViewModelInitializeComponentсResolveType.Diобращается к контейнеру - Контейнер создаёт ViewModel с разрешением всех зависимостей
- View инициализируется полученным ViewModel
ViewModelInitializeComponent с Di
В Inspector:
ResolveType→ DiTypeSelector→ выберите конкретный тип ViewModel
TypeSelector отображает имя типа (строка), по которому контейнер находит нужную регистрацию.
Без DI — ручная инициализация
Если DI не используется, применяйте:
- Bootstrap-паттерн с
view.Initialize(viewModel)— см. Быстрый старт ViewInitializerсResolveType.ComponentилиResolveType.ScriptableObjectViewInitializerManualс передачей ViewModel из кода
См. также
- ViewInitializer — подробности об инициализации
- ViewModel — создание ViewModel
- Быстрый старт — инициализация без DI