AI prompts
base on The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine. # 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.16.6",
```
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<ActorPresenter>();
builder.Register<CharacterService>(Lifetime.Scoped);
builder.Register<IRouteSearch, AStarRouteSearch>(Lifetime.Singleton);
builder.RegisterComponentInHierarchy<ActorsView>();
}
}
```
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;
public ActorPresenter(
CharacterService service,
ActorsView actorsView)
{
this.service = service;
this.actorsView = actorsView;
}
void IStartable.Start()
{
// Scheduled at Start () on VContainer's own PlayerLoopSystem.
}
}
```
- 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<FooController>();
```
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
", Assign "at most 3 tags" to the expected json: {"id":"10063","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"