Source Generator
This feature requires Unity 2021.3 or later.
VContainer uses reflection for metaprogramming by default. However, there is an option to improve execution performance by replacing it with Roslyn Source Generator.
Source Generator is part of Roslyn's functionality as a C# compiler tool. It is a feature that allows additional source code to be plugged in without contaminating the human-written source code. Since the added code is in C#, it is more debuggable and maintainable than IL code generation or ExpressionTee at runtime. While there are programming languages out there that have mechanisms such as "macros" built into their syntax, Source Generator has one thing in common in that it generates source code at compile time. This is a standard meta-programming approach in the new .NET environment.
In the old version of VContainer, this feature was used by IL weaving using Mono.Cecil
.
Since VContainer 1.13.0, we have moved to Roslyn Source Generator.
How to enable VContainer Source Generator
1. Add VContainer.SourceGenerator.dll
to your project.
Download `VContainer.SourceGenerator.dll from the release page. https://github.com/hadashiA/VContainer/releases
And Add this to somewhere under Assets/ folder in your project.
2. Mark as RoslynAnalyzer
Select VcContainer.SourceGenerator.dll
in project.
And, click label icon in bottom of the inspector window.
Enter “RoslynAnalyzer” into the text input window in the Asset Labels sub-menu.
Then, from the inspector, do the following:
- Go to Select platforms for plugin and disable Any Platform.
- Go to Include Platforms and disable Editor and Standalone.
See more information:
Which classes are target to code generation?
By default, classes in the assembly that reference VContainer.asmdef are target to code generation.
If you want to exclude a target for reasons such as wanting to suppress unnecessary code generation, please add the [InjectIgnore] attribute to the type.
Limitation
SourceGenerator acceleration is not supported for type definitions like the following. (works by reflection)
- Nested classes
- Struct
- If the access level is less than internal (for example, private), even if
[Inject]
is added, SourceGenerator is not supported.
Remarks
With VContainer, for example, the following code (as IL) is automatically generated:
class ClassA
{
private sealed class __GeneratedInjector : IInjector
{
public object CreateInstance(IObjectResolver resolver, IReadOnlyList<IInjectParameter> parameters)
{
I6 fromConstructor = resolver.ResolveOrParameter<I6>("fromConstructor1", parameters);
I7 fromConstructor2 = resolver.ResolveOrParameter<I7>("fromConstructor2", parameters);
return new ClassA(fromConstructor, fromConstructor2);
}
public void Inject(object instance, IObjectResolver resolver, IReadOnlyList<IInjectParameter> parameters)
{
ClassA clasA = (ClassA)instance;
I3 service = resolver.ResolveOrParameter<I3>("service3", parameters);
I4 service2 = resolver.ResolveOrParameter<I4>("service4", parameters);
allInjectionFeatureService.MethodInjectable1(service, service2);
I5 service3 = resolver.ResolveOrParameter<I5>("service5", parameters);
I6 service4 = resolver.ResolveOrParameter<I6>("service6", parameters);
classA.MethodInjectable2(service3, service4);
classA.PrivatePropertyInjectable = resolver.Resolve<I2>();
classA.PublicPropertyInjectable = resolver.Resolve<I3>();
classA.privateFieldInjectable = resolver.Resolve<I4>();
classA.PublicFieldInjectable = resolver.Resolve<I5>();
}
}