t1k:unity:tof:registration
| Field | Value |
|---|---|
| Module | tof |
| Version | 2.2.2 |
| Effort | low |
| Tools | — |
Keywords: asmdef, di, feature integration, gamelifetimescope, link.xml, register, theonefeature, tof, vcontainer
How to invoke
Section titled “How to invoke”/t1k:unity:tof:registrationTheOneFeature DI Registration
Section titled “TheOneFeature DI Registration”Integrating a TheOneFeature module into a Unity consumer project requires updating three files in lockstep. Missing any one produces a silent failure mode (compile OK + runtime null, or IL2CPP strip on device).
The Triplet
Section titled “The Triplet”| File | Purpose | Failure if skipped |
|---|---|---|
Assets/Scripts/GameLifetimeScope.cs | using + builder.Register<Feature>() call in Configure() | DI container has no binding → runtime VContainerException / null injection |
Assets/Scripts/Game.asmdef | Add the feature’s .DI assembly to references | Compile error: namespace not found |
Assets/Scripts/link.xml | <assembly fullname="..." preserve="all"/> | Works in Editor; IL2CPP strips on Android/iOS build → runtime crash on device only |
Canonical Pattern
Section titled “Canonical Pattern”// GameLifetimeScope.cs — top of fileusing TheOne.Features.RaceEvent.Core.DI;using TheOne.Features.PeriodRewardAds.DI;
// inside Configure(IContainerBuilder builder), in the feature-registration regionbuilder.RegisterRaceEvent();builder.RegisterPeriodRewardAds();Game.asmdef — append to the references array (asmdef is strict JSON, no comments allowed):
"TheOne.Features.RaceEvent.Core.DI","TheOne.Features.PeriodRewardAds.DI"<assembly fullname="TheOne.Features.RaceEvent" preserve="all"/><assembly fullname="TheOne.Features.PeriodRewardAds" preserve="all"/><assembly fullname="TheOne.Features.PeriodRewardAds.DI" preserve="all"/>Naming Conventions (Observed)
Section titled “Naming Conventions (Observed)”- DI namespace:
TheOne.Features.<FeatureName>[.Core].DI - Registration extension method:
builder.Register<FeatureName>()— match the method exported by the DI assembly (browse package source if unsure) link.xmlpreserves the runtime assembly (no.DIsuffix) AND the.DIassembly when a.DIexists separately. When in doubt, preserve both.
Sub-Feature Companions
Section titled “Sub-Feature Companions”Some features pull in UI/leaderboard companion assemblies that need their own preserves but no Register*() call. Examples:
PeriodRewardAds→ also preserveTheOne.Features.Puzzle.UI.Donate.Period,TheOne.Features.Puzzle.UI.IAA,TheOne.UI.Common.PeriodUI.Leaderboard.Core→ also requiresTheOne.Features.PlayFab.Coreas an asmdef reference even though there’s no directusing(transitive type leak via configs).
Verification Steps
Section titled “Verification Steps”- Compile in Editor — confirms asmdef edits.
- Search for
[Inject]on the feature’s services to confirm theRegister*()extension actually binds them. - IL2CPP build on a device before declaring done — the only way to catch a missing
link.xmlentry. Editor and Mono builds will not surface the strip.
Order in Configure()
Section titled “Order in Configure()”Append new builder.Register*() calls inside the existing feature-registration region (after the last Register*() call, before #endregion). Do not reorder existing registrations — VContainer resolves lazily, but registration order matters when one feature’s Configure* lambda references another feature’s binding.
Gotchas
Section titled “Gotchas”asmdefis JSON, not JSON5 — no trailing commas, no comments. Many consumerGame.asmdeffiles have no trailing newline; preserve that to keep the diff minimal.link.xmlorder does not matter, but group related preserves together for diff readability.- No service-locator fallback. TheOneFeature modules are pure DI —
ProjectContext.Instance.Container.Resolve<T>()is forbidden by MainGame governance. All access must be via constructor[Inject]. - Avoid
RegisterX()outside the region. GameLifetimeScope has multiple#regionblocks; new TOF registrations belong in the same block as the existingRegisterLocalization()/RegisterDefaultClaimRewardHandler()calls.