# vcontainer **Repository Path**: mirrors/vcontainer ## Basic Information - **Project Name**: vcontainer - **Description**: 在 Unity 游戏引擎上运行的超快 DI (Dependency Injection) 库 - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: https://www.oschina.net/p/vcontainer - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2025-03-11 - **Last Updated**: 2025-08-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # VContainer ![](https://github.com/hadashiA/VContainer/workflows/Test/badge.svg) ![](https://img.shields.io/badge/unity-2018.4+-000.svg) [![Releases](https://img.shields.io/github/release/hadashiA/VContainer.svg)](https://github.com/hadashiA/VContainer/releases) [![openupm](https://img.shields.io/npm/v/jp.hadashikick.vcontainer?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/jp.hadashikick.vcontainer/) 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. ## Features - 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* ## Documentation Visit [vcontainer.hadashikick.jp](https://vcontainer.hadashikick.jp) to view the full documentation. ## Performance ![](./website/static/img/benchmark_result.png) ### GC Alloc Result Example ![](./website/static/img/gc_alloc_profiler_result.png) ![](./website/static/img/screenshot_profiler_vcontainer.png) ![](./website/static/img/screenshot_profiler_zenject.png) ## Installation *Requires Unity 2018.4+* ### Install via UPM (using Git URL) 1. Navigate to your project's Packages folder and open the manifest.json file. 2. Add this line below the "dependencies": { line - ```json title="Packages/manifest.json" "jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.17.0", ``` 3. UPM should now install the package. ### Install via OpenUPM 1. The package is available on the [openupm registry](https://openupm.com). It's recommended to install it via [openupm-cli](https://github.com/openupm/openupm-cli). 2. Execute the openum command. - ``` openupm add jp.hadashikick.vcontainer ``` ### Install manually (using .unitypackage) 1. Download the .unitypackage from [releases](https://github.com/hadashiA/VContainer/releases) page. 2. Open VContainer.x.x.x.unitypackage ## Basic Usage First, create a scope. References are automatically resolved for types registered here. ```csharp public class GameLifetimeScope : LifetimeScope { public override void Configure(IContainerBuilder builder) { builder.RegisterEntryPoint(); builder.Register(Lifetime.Scoped); builder.Register(Lifetime.Singleton); builder.RegisterComponentInHierarchy(); } } ``` Where definitions of classes are ```csharp public interface IRouteSearch { } public class AStarRouteSearch : IRouteSearch { } public class CharacterService { readonly IRouteSearch routeSearch; public CharacterService(IRouteSearch routeSearch) { this.routeSearch = routeSearch; } } ``` ```csharp public class ActorsView : MonoBehaviour { } ``` and ```csharp public class ActorPresenter : IStartable { readonly CharacterService service; readonly ActorsView actorsView; readonly IWeapon primaryWeapon; readonly IWeapon secondaryWeapon; readonly IWeapon specialWeapon; public ActorPresenter( CharacterService service, ActorsView actorsView, [Key(WeaponType.Primary)] IWeapon primaryWeapon, [Key(WeaponType.Secondary)] IWeapon secondaryWeapon, [Key(WeaponType.Special)] IWeapon specialWeapon) { this.service = service; this.actorsView = actorsView; this.primaryWeapon = primaryWeapon; this.secondaryWeapon = secondaryWeapon; this.specialWeapon = specialWeapon; } void IStartable.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". ### Flexible Scoping with async LifetimeScope can dynamically create children. This allows you to deal with the asynchronous resource loading that often occurs in games. ```csharp public void LoadLevel() { // ... Loading some assets // Create a child scope instantScope = currentScope.CreateChild(); // Create a child scope with LifetimeScope prefab instantScope = currentScope.CreateChildFromPrefab(lifetimeScopePrefab); // Create a child with additional registration instantScope = currentScope.CreateChildFromPrefab( lifetimeScopePrefab, builder => { // Extra Registrations ... }); instantScope = currentScope.CreateChild(builder => { // ExtraRegistrations ... }); instantScope = currentScope.CreateChild(extraInstaller); } public void UnloadLevel() { instantScope.Dispose(); } ``` In addition, you can create a parent-child relationship with LifetimeScope in an Additive scene. ```csharp class SceneLoader { readonly LifetimeScope currentScope; public SceneLoader(LifetimeScope currentScope) { this.currentScope = currentScope; // Inject the LifetimeScope to which this class belongs } IEnumerator LoadSceneAsync() { // 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`. var loading = SceneManager.LoadSceneAsync("...", LoadSceneMode.Additive); while (!loading.isDone) { yield return null; } } } // UniTask example async UniTask LoadSceneAsync() { using (LifetimeScope.EnqueueParent(parent)) { await SceneManager.LoadSceneAsync("...", LoadSceneMode.Additive); } } } ``` ```csharp // LifetimeScopes generated during this block will be additionally Registered. using (LifetimeScope.Enqueue(builder => { // Register for the next scene not yet loaded builder.RegisterInstance(extraInstance); })) { // Loading the scene.. } ``` See [scoping](https://vcontainer.hadashikick.jp/scoping/lifetime-overview) for more information. ## UniTask ```csharp public class FooController : IAsyncStartable { public async UniTask StartAsync(CancellationToken cancellation) { await LoadSomethingAsync(cancellation); await ... ... } } ``` ```csharp builder.RegisterEntryPoint(); ``` See [integrations](https://vcontainer.hadashikick.jp/integrations/unitask) for more information. ## Diagnostics Window ![](./website/static/img/screenshot_diagnostics_window.png) See [diagnostics](https://vcontainer.hadashikick.jp/diagnostics/diagnostics-window) for more information. ## Credits VContainer is inspired by: - [Zenject](https://github.com/modesttree/Zenject) / [Extenject](https://github.com/svermeulen/Extenject). - [Autofac](http://autofac.org) - [Autofac Project](https://github.com/autofac/Autofac). - [MicroResolver](https://github.com/neuecc/MicroResolver) ## Author [@hadashiA](https://twitter.com/hadashiA) ## License MIT