The extra fast DI (Dependency Injection) library running on Unity Game Engine.
"V" means making Unity's initial "U" more thinner and solid ... !
- Fast Resolve: Basically 5-10x faster than Zenject.
- Minimum GC Allocation: In Resolve, we have zero allocation without spawned instances.
- Small code size: Few internal types and few .callvirt.
- Assisting correct DI way: Provides simple and transparent API, and carefully select features. This prevents the DI declaration from becoming overly complex.
- Immutable Container: Thread safety and robustness.
- Constructor Injection / Method Injection / Property & Field Injection
- Dispatch own PlayerLoopSystem
- Flexible scoping
- Application can freely create nested Lifetime Scope with any async way for you like.
- Accelerated mode with SourceGenerator (Optional)
- Diagnositcs window on unity editor
- UniTask Integration
- ECS Integration beta
Visit vcontainer.hadashikick.jp to view the full documentation.
Requires Unity 2018.4+
- Navigate to your project's Packages folder and open the manifest.json file.
- Add this line below the "dependencies": { line
"jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.17.0",
- UPM should now install the package.
- The package is available on the openupm registry. It's recommended to install it via openupm-cli.
- Execute the openum command.
openupm add jp.hadashikick.vcontainer
- Download the .unitypackage from releases page.
- Open VContainer.x.x.x.unitypackage
First, create a scope. References are automatically resolved for types registered here.
publicclassGameLifetimeScope:LifetimeScope{publicoverridevoidConfigure(IContainerBuilderbuilder){builder.RegisterEntryPoint<ActorPresenter>();builder.Register<CharacterService>(Lifetime.Scoped);builder.Register<IRouteSearch,AStarRouteSearch>(Lifetime.Singleton);builder.RegisterComponentInHierarchy<ActorsView>();}}Where definitions of classes are
publicinterfaceIRouteSearch{}publicclassAStarRouteSearch:IRouteSearch{}publicclassCharacterService{readonlyIRouteSearchrouteSearch;publicCharacterService(IRouteSearchrouteSearch){this.routeSearch=routeSearch;}}publicclassActorsView:MonoBehaviour{}and
publicclassActorPresenter:IStartable{readonlyCharacterServiceservice;readonlyActorsViewactorsView;readonlyIWeaponprimaryWeapon;readonlyIWeaponsecondaryWeapon;readonlyIWeaponspecialWeapon;publicActorPresenter(CharacterServiceservice,ActorsViewactorsView,[Key(WeaponType.Primary)]IWeaponprimaryWeapon,[Key(WeaponType.Secondary)]IWeaponsecondaryWeapon,[Key(WeaponType.Special)]IWeaponspecialWeapon){this.service=service;this.actorsView=actorsView;this.primaryWeapon=primaryWeapon;this.secondaryWeapon=secondaryWeapon;this.specialWeapon=specialWeapon;}voidIStartable.Start(){// Scheduled at Start () on VContainer's own PlayerLoopSystem.}}You can also resolve with object-based Key directly from the container:
- In this example, the routeSearch of CharacterService is automatically set as the instance of AStarRouteSearch when CharacterService is resolved.
- Further, VContainer can have a Pure C# class as an entry point. (Various timings such as Start, Update, etc. can be specified.) This facilitates "separation of domain logic and presentation".
LifetimeScope can dynamically create children. This allows you to deal with the asynchronous resource loading that often occurs in games.
publicvoidLoadLevel(){// ... Loading some assets// Create a child scopeinstantScope=currentScope.CreateChild();// Create a child scope with LifetimeScope prefabinstantScope=currentScope.CreateChildFromPrefab(lifetimeScopePrefab);// Create a child with additional registrationinstantScope=currentScope.CreateChildFromPrefab(lifetimeScopePrefab,
builder =>{// Extra Registrations ...});instantScope=currentScope.CreateChild(builder =>{// ExtraRegistrations ...});instantScope=currentScope.CreateChild(extraInstaller);}publicvoidUnloadLevel(){instantScope.Dispose();}In addition, you can create a parent-child relationship with LifetimeScope in an Additive scene.
classSceneLoader{readonlyLifetimeScopecurrentScope;publicSceneLoader(LifetimeScopecurrentScope){this.currentScope=currentScope;// Inject the LifetimeScope to which this class belongs}IEnumeratorLoadSceneAsync(){// LifetimeScope generated in this block will be parented by `this.lifetimeScope`using(LifetimeScope.EnqueueParent(currentScope)){// If this scene has a LifetimeScope, its parent will be `parent`.varloading=SceneManager.LoadSceneAsync("...",LoadSceneMode.Additive);while(!loading.isDone){yieldreturnnull;}}}// UniTask exampleasyncUniTaskLoadSceneAsync(){using(LifetimeScope.EnqueueParent(parent)){awaitSceneManager.LoadSceneAsync("...",LoadSceneMode.Additive);}}}// LifetimeScopes generated during this block will be additionally Registered.using(LifetimeScope.Enqueue(builder =>{// Register for the next scene not yet loadedbuilder.RegisterInstance(extraInstance);})){// Loading the scene..}See scoping for more information.
publicclassFooController:IAsyncStartable{publicasyncUniTaskStartAsync(CancellationTokencancellation){awaitLoadSomethingAsync(cancellation);await ...
...}}builder.RegisterEntryPoint<FooController>();See integrations for more information.
See diagnostics for more information.
VContainer is inspired by:
MIT




