{"id":14960407,"url":"https://github.com/hadashia/vcontainer","last_synced_at":"2025-05-14T05:10:21.413Z","repository":{"id":38194446,"uuid":"268788240","full_name":"hadashiA/VContainer","owner":"hadashiA","description":"The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.","archived":false,"fork":false,"pushed_at":"2025-05-06T04:52:39.000Z","size":15084,"stargazers_count":2263,"open_issues_count":76,"forks_count":199,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-05-06T05:32:55.858Z","etag":null,"topics":["dependency-injection","di","unity","unity3d"],"latest_commit_sha":null,"homepage":"https://vcontainer.hadashikick.jp","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hadashiA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"hadashiA"}},"created_at":"2020-06-02T11:57:34.000Z","updated_at":"2025-05-06T04:52:47.000Z","dependencies_parsed_at":"2023-02-19T09:16:15.363Z","dependency_job_id":"2eecf0e8-3c14-4bb4-86a0-fb58d272c7bf","html_url":"https://github.com/hadashiA/VContainer","commit_stats":{"total_commits":878,"total_committers":68,"mean_commits":"12.911764705882353","dds":"0.22665148063781326","last_synced_commit":"afaeff82040994f7836afa9f5116eb52a4e54f69"},"previous_names":[],"tags_count":75,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadashiA%2FVContainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadashiA%2FVContainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadashiA%2FVContainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadashiA%2FVContainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hadashiA","download_url":"https://codeload.github.com/hadashiA/VContainer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254076850,"owners_count":22010611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","di","unity","unity3d"],"created_at":"2024-09-24T13:22:12.855Z","updated_at":"2025-05-14T05:10:21.362Z","avatar_url":"https://github.com/hadashiA.png","language":"C#","readme":"# VContainer\n\n![](https://github.com/hadashiA/VContainer/workflows/Test/badge.svg)\n![](https://img.shields.io/badge/unity-2018.4+-000.svg)\n[![Releases](https://img.shields.io/github/release/hadashiA/VContainer.svg)](https://github.com/hadashiA/VContainer/releases)\n[![openupm](https://img.shields.io/npm/v/jp.hadashikick.vcontainer?label=openupm\u0026registry_uri=https://package.openupm.com)](https://openupm.com/packages/jp.hadashikick.vcontainer/)\n\nThe extra fast DI (Dependency Injection) library running on Unity Game Engine.\n\n\"V\" means making Unity's initial \"U\" more thinner and solid ... !\n\n- **Fast Resolve:** Basically 5-10x faster than Zenject.\n- **Minimum GC Allocation:** In Resolve, we have **zero allocation** without spawned instances.\n- **Small code size:** Few internal types and few .callvirt.\n- **Assisting correct DI way:** Provides simple and transparent API, and carefully select features. This prevents the DI declaration from becoming overly complex.\n- **Immutable Container:** Thread safety and robustness.\n\n## Features\n\n- Constructor Injection / Method Injection / Property \u0026 Field Injection\n- Dispatch own PlayerLoopSystem\n- Flexible scoping\n  - Application can freely create nested Lifetime Scope with any async way for you like.\n- Accelerated mode with SourceGenerator (Optional)\n- Diagnositcs window on unity editor\n- UniTask Integration\n- ECS Integration *beta*\n\n## Documentation\n\nVisit [vcontainer.hadashikick.jp](https://vcontainer.hadashikick.jp) to view the full documentation.\n\n## Performance\n\n![](./website/static/img/benchmark_result.png)\n\n### GC Alloc Result Example\n\n![](./website/static/img/gc_alloc_profiler_result.png)\n\n![](./website/static/img/screenshot_profiler_vcontainer.png)\n\n![](./website/static/img/screenshot_profiler_zenject.png)\n\n\n## Installation\n\n*Requires Unity 2018.4+*\n\n### Install via UPM (using Git URL)\n\n1. Navigate to your project's Packages folder and open the manifest.json file.\n2. Add this line below the \"dependencies\": { line\n    - ```json title=\"Packages/manifest.json\"\n      \"jp.hadashikick.vcontainer\": \"https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.16.8\",\n      ```\n3. UPM should now install the package.\n\n### Install via OpenUPM\n\n\n1. 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).\n2. Execute the openum command.\n    - ```\n      openupm add jp.hadashikick.vcontainer\n      ```\n\n### Install manually (using .unitypackage)\n\n1. Download the .unitypackage from [releases](https://github.com/hadashiA/VContainer/releases) page.\n2. Open VContainer.x.x.x.unitypackage\n\n## Basic Usage\n\nFirst, create a scope. References are automatically resolved for types registered here.\n\n```csharp\npublic class GameLifetimeScope : LifetimeScope\n{\n    public override void Configure(IContainerBuilder builder)\n    {\n        builder.RegisterEntryPoint\u003cActorPresenter\u003e();\n\n        builder.Register\u003cCharacterService\u003e(Lifetime.Scoped);\n        builder.Register\u003cIRouteSearch, AStarRouteSearch\u003e(Lifetime.Singleton);\n\n        builder.RegisterComponentInHierarchy\u003cActorsView\u003e();\n    }\n}\n```\n\nWhere definitions of classes are\n\n```csharp\npublic interface IRouteSearch\n{\n}\n\npublic class AStarRouteSearch : IRouteSearch\n{\n}\n\npublic class CharacterService\n{\n    readonly IRouteSearch routeSearch;\n\n    public CharacterService(IRouteSearch routeSearch)\n    {\n        this.routeSearch = routeSearch;\n    }\n}\n```\n\n```csharp\npublic class ActorsView : MonoBehaviour\n{\n}\n```\n\nand\n\n```csharp\npublic class ActorPresenter : IStartable\n{\n    readonly CharacterService service;\n    readonly ActorsView actorsView;\n\n    public ActorPresenter(\n        CharacterService service,\n        ActorsView actorsView)\n    {\n        this.service = service;\n        this.actorsView = actorsView;\n    }\n\n    void IStartable.Start()\n    {\n        // Scheduled at Start () on VContainer's own PlayerLoopSystem.\n    }\n}\n```\n\n\n- In this example, the routeSearch of CharacterService is automatically set as the instance of AStarRouteSearch when CharacterService is resolved.\n- 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\".\n\n### Flexible Scoping with async\n\nLifetimeScope can dynamically create children. This allows you to deal with the asynchronous resource loading that often occurs in games.\n\n```csharp\npublic void LoadLevel()\n{\n    // ... Loading some assets\n\n    // Create a child scope\n    instantScope = currentScope.CreateChild();\n\n    // Create a child scope with LifetimeScope prefab\n    instantScope = currentScope.CreateChildFromPrefab(lifetimeScopePrefab);\n\n    // Create a child with additional registration\n    instantScope = currentScope.CreateChildFromPrefab(\n        lifetimeScopePrefab,\n        builder =\u003e\n        {\n            // Extra Registrations ...\n        });\n\n    instantScope = currentScope.CreateChild(builder =\u003e\n    {\n        // ExtraRegistrations ...\n    });\n\n    instantScope = currentScope.CreateChild(extraInstaller);\n}\n\npublic void UnloadLevel()\n{\n    instantScope.Dispose();\n}\n```\n\nIn addition, you can create a parent-child relationship with LifetimeScope in an Additive scene.\n\n```csharp\nclass SceneLoader\n{\n    readonly LifetimeScope currentScope;\n\n    public SceneLoader(LifetimeScope currentScope)\n    {\n        this.currentScope = currentScope; // Inject the LifetimeScope to which this class belongs\n    }\n\n    IEnumerator LoadSceneAsync()\n    {\n        // LifetimeScope generated in this block will be parented by `this.lifetimeScope`\n        using (LifetimeScope.EnqueueParent(currentScope))\n        {\n            // If this scene has a LifetimeScope, its parent will be `parent`.\n            var loading = SceneManager.LoadSceneAsync(\"...\", LoadSceneMode.Additive);\n            while (!loading.isDone)\n            {\n                yield return null;\n            }\n        }\n    }\n\n    // UniTask example\n    async UniTask LoadSceneAsync()\n    {\n        using (LifetimeScope.EnqueueParent(parent))\n        {\n            await SceneManager.LoadSceneAsync(\"...\", LoadSceneMode.Additive);\n        }\n    }\n}\n```\n\n```csharp\n// LifetimeScopes generated during this block will be additionally Registered.\nusing (LifetimeScope.Enqueue(builder =\u003e\n{\n    // Register for the next scene not yet loaded\n    builder.RegisterInstance(extraInstance);\n}))\n{\n    // Loading the scene..\n}\n```\n\nSee [scoping](https://vcontainer.hadashikick.jp/scoping/lifetime-overview) for more information.\n\n## UniTask\n\n```csharp\npublic class FooController : IAsyncStartable\n{\n    public async UniTask StartAsync(CancellationToken cancellation)\n    {\n        await LoadSomethingAsync(cancellation);\n        await ...\n        ...\n    }\n}\n```\n\n```csharp\nbuilder.RegisterEntryPoint\u003cFooController\u003e();\n```\n\nSee [integrations](https://vcontainer.hadashikick.jp/integrations/unitask) for more information.\n\n\n## Diagnostics Window\n\n![](./website/static/img/screenshot_diagnostics_window.png)\n\nSee [diagnostics](https://vcontainer.hadashikick.jp/diagnostics/diagnostics-window) for more information.\n\n## Credits\n\nVContainer is inspired by:\n\n- [Zenject](https://github.com/modesttree/Zenject) / [Extenject](https://github.com/svermeulen/Extenject).\n- [Autofac](http://autofac.org) - [Autofac Project](https://github.com/autofac/Autofac).\n- [MicroResolver](https://github.com/neuecc/MicroResolver)\n\n## Author\n\n[@hadashiA](https://twitter.com/hadashiA)\n\n## License\n\nMIT\n","funding_links":["https://github.com/sponsors/hadashiA"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhadashia%2Fvcontainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhadashia%2Fvcontainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhadashia%2Fvcontainer/lists"}