Extend VContainer DI: eliminate manual composition and duplicate references

- Register InventoryModel, ShopModel as container-managed singletons
- Register GameController, ShopController, InventoryController via RegisterComponent
- Replace [SerializeField] with [Inject] for service dependencies in controllers
- Move maxActiveModifierSlots config to GameLifetimeScope (composition root)
- Remove manual model creation and Initialize() calls from GameController
- Add ToggleVisibility() to ShopController/InventoryController, removing GetComponentInChildren
- Move event subscriptions from Awake to Start for safe VContainer injection order
- Transfer game startup orchestration to GameController.Start()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 16:14:44 +07:00
parent 6c10a35bf9
commit 3c50415111
5 changed files with 116 additions and 98 deletions
+45 -75
View File
@@ -16,43 +16,56 @@ namespace YachtDice.UI
{
public class GameController : MonoBehaviour
{
[Header("Model")]
[SerializeField] private GameManager gameManager;
[SerializeField] private ScoringSystem scoringSystem;
[SerializeField] private DiceManager diceManager;
[Header("Views")]
[SerializeField] private ScoreCardView scoreCardView;
[SerializeField] private DicePanelView dicePanelView;
[SerializeField] private GameInfoView gameInfoView;
[Header("Economy & Modifiers")]
[SerializeField] private CurrencyBank currencyBank;
[SerializeField] private ShopController shopController;
[SerializeField] private InventoryController inventoryController;
[Header("Settings")]
[SerializeField] private int maxRollsPerTurn = 3;
[SerializeField] private int maxActiveModifierSlots = 5;
private const int UpperBonusThreshold = 63;
private const int UpperBonusValue = 35;
private GameManager gameManager;
private ScoringSystem scoringSystem;
private DiceManager diceManager;
private CurrencyBank currencyBank;
private ShopController shopController;
private InventoryController inventoryController;
private ModifierRegistry modifierRegistry;
private CategoryCatalog categoryCatalog;
private InventoryModel inventoryModel;
private ModifierCatalogSO modifierCatalog;
private ShopModel shopModel;
[Inject]
public void Construct(ModifierRegistry modifierRegistry, CategoryCatalog categoryCatalog)
public void Construct(
GameManager gameManager,
ScoringSystem scoringSystem,
DiceManager diceManager,
CurrencyBank currencyBank,
ShopController shopController,
InventoryController inventoryController,
ModifierRegistry modifierRegistry,
CategoryCatalog categoryCatalog,
ModifierCatalogSO modifierCatalog,
ShopModel shopModel)
{
this.gameManager = gameManager;
this.scoringSystem = scoringSystem;
this.diceManager = diceManager;
this.currencyBank = currencyBank;
this.shopController = shopController;
this.inventoryController = inventoryController;
this.modifierRegistry = modifierRegistry;
this.categoryCatalog = categoryCatalog;
this.modifierCatalog = modifierCatalog;
this.shopModel = shopModel;
}
// ── Lifecycle ──────────────────────────────────────────────
private void Awake()
private void Start()
{
// Model → Controller
gameManager.OnTurnStarted += HandleTurnStarted;
@@ -69,17 +82,17 @@ namespace YachtDice.UI
gameInfoView.OnShopClicked += HandleShopClicked;
gameInfoView.OnInventoryClicked += HandleInventoryClicked;
// Currency
if (currencyBank != null)
currencyBank.OnBalanceChanged += HandleCurrencyChanged;
}
// Currency & Modifiers
currencyBank.OnBalanceChanged += HandleCurrencyChanged;
modifierRegistry.OnChanged += HandleInventoryChangedForSave;
private void Start()
{
// Инициализируем скоркарту из каталога категорий
// Initialize
scoreCardView.Initialize(categoryCatalog);
LoadSaveData();
gameInfoView.SetCurrencyText(currencyBank.Balance);
InitializeModifierSystems();
// Start the game after all subscriptions are in place
gameManager.StartNewGame();
}
private void OnDestroy()
@@ -97,49 +110,22 @@ namespace YachtDice.UI
gameInfoView.OnShopClicked -= HandleShopClicked;
gameInfoView.OnInventoryClicked -= HandleInventoryClicked;
if (currencyBank != null)
currencyBank.OnBalanceChanged -= HandleCurrencyChanged;
currencyBank.OnBalanceChanged -= HandleCurrencyChanged;
if (modifierRegistry != null)
modifierRegistry.OnChanged -= HandleInventoryChangedForSave;
}
// ── Modifier System Init ─────────────────────────────────
// ── Save / Load ─────────────────────────────────────────
private void InitializeModifierSystems()
{
if (modifierRegistry == null)
modifierRegistry = new ModifierRegistry(maxActiveModifierSlots);
else
modifierRegistry.SetMaxActiveSlots(maxActiveModifierSlots);
modifierRegistry.OnChanged += HandleInventoryChangedForSave;
inventoryModel = new InventoryModel(modifierRegistry);
shopModel = new ShopModel(currencyBank, inventoryModel);
ModifierCatalogSO catalog = shopController != null ? shopController.Catalog : null;
LoadSaveData(catalog);
if (inventoryController != null)
inventoryController.Initialize(inventoryModel);
if (shopController != null)
shopController.Initialize(shopModel);
if (currencyBank != null)
gameInfoView.SetCurrencyText(currencyBank.Balance);
}
private void LoadSaveData(ModifierCatalogSO catalog)
private void LoadSaveData()
{
SaveData save = SaveSystem.Load();
if (currencyBank != null && save.Currency > 0)
if (save.Currency > 0)
currencyBank.SetBalance(save.Currency);
if (catalog != null && save.OwnedModifiers.Count > 0)
if (modifierCatalog != null && save.OwnedModifiers.Count > 0)
{
var entries = new List<ModifierSaveEntry>();
var permanentIds = new HashSet<string>();
@@ -147,7 +133,7 @@ namespace YachtDice.UI
for (int i = 0; i < save.OwnedModifiers.Count; i++)
{
var oldEntry = save.OwnedModifiers[i];
var def = catalog.FindById(oldEntry.ModifierId);
var def = modifierCatalog.FindById(oldEntry.ModifierId);
if (def == null)
{
@@ -168,7 +154,7 @@ namespace YachtDice.UI
permanentIds.Add(def.Id);
}
modifierRegistry.LoadSaveData(entries, catalog);
modifierRegistry.LoadSaveData(entries, modifierCatalog);
shopModel.LoadPurchasedPermanentIds(permanentIds);
}
}
@@ -177,7 +163,7 @@ namespace YachtDice.UI
{
var save = new SaveData
{
Currency = currencyBank != null ? currencyBank.Balance : 0
Currency = currencyBank.Balance
};
var entries = modifierRegistry.GetSaveData();
@@ -277,28 +263,12 @@ namespace YachtDice.UI
private void HandleShopClicked()
{
if (shopController != null)
{
var shopView = shopController.GetComponentInChildren<ShopView>(true);
if (shopView != null)
{
if (shopView.IsVisible) shopView.Hide();
else shopView.Show();
}
}
shopController.ToggleVisibility();
}
private void HandleInventoryClicked()
{
if (inventoryController != null)
{
var inventoryView = inventoryController.GetComponentInChildren<InventoryView>(true);
if (inventoryView != null)
{
if (inventoryView.IsVisible) inventoryView.Hide();
else inventoryView.Show();
}
}
inventoryController.ToggleVisibility();
}
private void HandleCurrencyChanged(int newBalance)