DICS (pronounced dee-see-es) is a staged dependency injection library for C# —
a simplified port of the core ideas in DIstage.
It runs on plain .NET (netstandard2.1) and inside Unity.
NuGet (plain .NET, netstandard2.1):
dotnet add package DICS
The package carries DICS.Generator as a Roslyn analyzer, so [LiftConstructor],
[LiftInitializer], and [LiftFactory] work as soon as the package is referenced.
Unity — add the package by git URL, via Window → Package Manager → Add package
from git URL, or directly in Packages/manifest.json:
{
"dependencies": {
"com.playq.dics": "https://github.com/PlayQ/dics.git",
"com.unity.nuget.newtonsoft-json": "3.2.1"
}
}
Unity 2021.3 or newer. com.unity.nuget.newtonsoft-json is a real dependency, not a
convenience: under Unity TraceGen serializes profiles with Newtonsoft, and only
falls back to System.Text.Json off-Unity.
Unity does not pick up the source generator from this repository — DICS.Generator
is restricted to a platform Unity does not compile for in the editor, and no
pre-built analyzer assembly is committed. Under Unity, either lift constructors and
initializers by hand, or build DICS.Generator and drop the DLL into the project as
an asset labelled RoslynAnalyzer.
DICS is a three-pass tool:
Locator containing every
produced instance.This separation makes DI debuggable: the Plan is a value you can print, diff, or
serialize, and instantiation never reflects against Type beyond typeof and
equality comparison.
DICS is one instance of the Percept-Plan-Execute-Repeat metaprogramming pattern formulated by pshirshov in 2014.
Background reading: the DIstage manual.
MonoModule, scenes, prefabs, tickables,
cancellation tokens.IAsyncFunctoid, IAsyncInitializer,
ProduceAsync, generator support, cancellation, parallelism.public class MyModule : Module
{
public MyModule()
{
Make<int>().From().Instance(42);
Make<string>().From().Functoid(
IFunctoid.Lift((int n) => $"answer={n}")
);
}
}
var injector = new Injector(ILocator.Empty, IDicsMeasurement.FromDefault(), "demo",
new MyModule().Freeze());
ILocator loc = injector.Produce(Key.Of<string>());
Console.WriteLine(loc.Get<string>()); // answer=42
The async equivalent (see docs/async.md):
ILocator loc = await injector.ProduceAsync(ct, Key.Of<string>());
| Concept | What it is |
|---|---|
Key | A (Type, name?) identifier for an instance. |
Binding | "How to make this key": instance, ref, functoid, lifecycle. |
Module | A collection of bindings, plus DSL to build them. Modules concatenate. |
Plan | A DAG of operations derived from your modules and roots. Validates wiring. |
Locator | The "world" produced by executing a Plan. |
Injector | Turns modules into plans and plans into locators. |
Provider | Runtime-introspectable representation of a function. |
Initializer | Like a provider, but mutates an existing instance. |
typeof/Type.Equals. Constructors and initializers are
represented as functoids, either hand-written or generated.DICS.Generator source generators.// ReSharper disable PartialTypeWithSinglePart in files with partial
classes (or disable the inspection globally) so ReSharper does not strip
partial from generator-driven types.DICS is licensed under the MIT License.
C#
99.6%
DICS (pronounced dee-see-es) is a staged dependency injection library for C# —
a simplified port of the core ideas in DIstage.
It runs on plain .NET (netstandard2.1) and inside Unity.
NuGet (plain .NET, netstandard2.1):
dotnet add package DICS
The package carries DICS.Generator as a Roslyn analyzer, so [LiftConstructor],
[LiftInitializer], and [LiftFactory] work as soon as the package is referenced.
Unity — add the package by git URL, via Window → Package Manager → Add package
from git URL, or directly in Packages/manifest.json:
{
"dependencies": {
"com.playq.dics": "https://github.com/PlayQ/dics.git",
"com.unity.nuget.newtonsoft-json": "3.2.1"
}
}
Unity 2021.3 or newer. com.unity.nuget.newtonsoft-json is a real dependency, not a
convenience: under Unity TraceGen serializes profiles with Newtonsoft, and only
falls back to System.Text.Json off-Unity.
Unity does not pick up the source generator from this repository — DICS.Generator
is restricted to a platform Unity does not compile for in the editor, and no
pre-built analyzer assembly is committed. Under Unity, either lift constructors and
initializers by hand, or build DICS.Generator and drop the DLL into the project as
an asset labelled RoslynAnalyzer.
DICS is a three-pass tool:
Locator containing every
produced instance.This separation makes DI debuggable: the Plan is a value you can print, diff, or
serialize, and instantiation never reflects against Type beyond typeof and
equality comparison.
DICS is one instance of the Percept-Plan-Execute-Repeat metaprogramming pattern formulated by pshirshov in 2014.
Background reading: the DIstage manual.
MonoModule, scenes, prefabs, tickables,
cancellation tokens.IAsyncFunctoid, IAsyncInitializer,
ProduceAsync, generator support, cancellation, parallelism.public class MyModule : Module
{
public MyModule()
{
Make<int>().From().Instance(42);
Make<string>().From().Functoid(
IFunctoid.Lift((int n) => $"answer={n}")
);
}
}
var injector = new Injector(ILocator.Empty, IDicsMeasurement.FromDefault(), "demo",
new MyModule().Freeze());
ILocator loc = injector.Produce(Key.Of<string>());
Console.WriteLine(loc.Get<string>()); // answer=42
The async equivalent (see docs/async.md):
ILocator loc = await injector.ProduceAsync(ct, Key.Of<string>());
| Concept | What it is |
|---|---|
Key | A (Type, name?) identifier for an instance. |
Binding | "How to make this key": instance, ref, functoid, lifecycle. |
Module | A collection of bindings, plus DSL to build them. Modules concatenate. |
Plan | A DAG of operations derived from your modules and roots. Validates wiring. |
Locator | The "world" produced by executing a Plan. |
Injector | Turns modules into plans and plans into locators. |
Provider | Runtime-introspectable representation of a function. |
Initializer | Like a provider, but mutates an existing instance. |
typeof/Type.Equals. Constructors and initializers are
represented as functoids, either hand-written or generated.DICS.Generator source generators.// ReSharper disable PartialTypeWithSinglePart in files with partial
classes (or disable the inspection globally) so ReSharper does not strip
partial from generator-driven types.DICS is licensed under the MIT License.
C#
99.6%