The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.
See the codeThe extra fast DI (Dependency Injection) library running on Unity Game Engine.
"V" means making Unity's initial "U" more thinner and solid ... !
Visit vcontainer.hadashikick.jp to view the full documentation.




Requires Unity 2018.4+
"jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.19.0",
openupm add jp.hadashikick.vcontainer
First, create a scope. References are automatically resolved for types registered here.
public class GameLifetimeScope : LifetimeScope
{
public override void Configure(IContainerBuilder builder)
{
builder.RegisterEntryPoint<ActorPresenter>();
builder.Register<CharacterService>(Lifetime.Scoped);
builder.Register<IRouteSearch, AStarRouteSearch>(Lifetime.Singleton);
builder.RegisterComponentInHierarchy<ActorsView>();
}
}
Where definitions of classes are
public interface IRouteSearch
{
}
public class AStarRouteSearch : IRouteSearch
{
}
public class CharacterService
{
readonly IRouteSearch routeSearch;
public CharacterService(IRouteSearch routeSearch)
{
this.routeSearch = routeSearch;
}
}
public class ActorsView : MonoBehaviour
{
}
and
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:
LifetimeScope can dynamically create children. This allows you to deal with the asynchronous resource loading that often occurs in games.
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.
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);
}
}
}
// 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 for more information.
public class FooController : IAsyncStartable
{
public async UniTask StartAsync(CancellationToken cancellation)
{
await LoadSomethingAsync(cancellation);
await ...
...
}
}
builder.RegisterEntryPoint<FooController>();
See integrations for more information.

See diagnostics for more information.
VContainer is inspired by:
MIT
4,143 followers · starred Jul 2020
114 followers · starred May 2023
22 followers · starred Aug 2022
139 followers · starred May 2026
The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.
See the codeThe extra fast DI (Dependency Injection) library running on Unity Game Engine.
"V" means making Unity's initial "U" more thinner and solid ... !
Visit vcontainer.hadashikick.jp to view the full documentation.




Requires Unity 2018.4+
"jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.19.0",
openupm add jp.hadashikick.vcontainer
First, create a scope. References are automatically resolved for types registered here.
public class GameLifetimeScope : LifetimeScope
{
public override void Configure(IContainerBuilder builder)
{
builder.RegisterEntryPoint<ActorPresenter>();
builder.Register<CharacterService>(Lifetime.Scoped);
builder.Register<IRouteSearch, AStarRouteSearch>(Lifetime.Singleton);
builder.RegisterComponentInHierarchy<ActorsView>();
}
}
Where definitions of classes are
public interface IRouteSearch
{
}
public class AStarRouteSearch : IRouteSearch
{
}
public class CharacterService
{
readonly IRouteSearch routeSearch;
public CharacterService(IRouteSearch routeSearch)
{
this.routeSearch = routeSearch;
}
}
public class ActorsView : MonoBehaviour
{
}
and
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:
LifetimeScope can dynamically create children. This allows you to deal with the asynchronous resource loading that often occurs in games.
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.
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);
}
}
}
// 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 for more information.
public class FooController : IAsyncStartable
{
public async UniTask StartAsync(CancellationToken cancellation)
{
await LoadSomethingAsync(cancellation);
await ...
...
}
}
builder.RegisterEntryPoint<FooController>();
See integrations for more information.

See diagnostics for more information.
VContainer is inspired by:
MIT
4,143 followers · starred Jul 2020
114 followers · starred May 2023
22 followers · starred Aug 2022
139 followers · starred May 2026