Hints are used to fine-tune code generation. The OnNewInstance hint determines whether to generate partial OnNewInstance method.
In addition, setup hints can be comments before the Setup method in the form hint = value
, for example: // OnNewInstance = On
.
using Shouldly;
using Pure.DI;
using static Pure.DI.Hint;
DI.Setup(nameof(Composition))
.Hint(OnNewInstance, "On")
.Hint(OnNewInstanceImplementationTypeNameWildcard, "*Dependency")
.Hint(OnNewInstanceImplementationTypeNameWildcard, "*Service")
.Bind().As(Lifetime.Singleton).To<Dependency>()
.Bind().To<Service>()
.Root<IService>("Root");
var log = new List<string>();
var composition = new Composition(log);
var service1 = composition.Root;
var service2 = composition.Root;
log.ShouldBe([
"Dependency created",
"Service created",
"Service created"]);
interface IDependency;
class Dependency : IDependency
{
public override string ToString() => nameof(Dependency);
}
interface IService
{
IDependency Dependency { get; }
}
class Service(IDependency dependency) : IService
{
public IDependency Dependency { get; } = dependency;
public override string ToString() => nameof(Service);
}
internal partial class Composition
{
private readonly List<string> _log = [];
public Composition(List<string> log) : this() =>
_log = log;
partial void OnNewInstance<T>(
ref T value,
object? tag,
Lifetime lifetime) =>
_log.Add($"{typeof(T).Name} created");
}
Running this code sample locally
- Make sure you have the .NET SDK 9.0 or later is installed
dotnet --list-sdk
- Create a net9.0 (or later) console application
dotnet new console -n Sample
dotnet add package Pure.DI
dotnet add package Shouldly
- Copy the example code into the Program.cs file
You are ready to run the example 🚀
dotnet run
The OnNewInstanceImplementationTypeNameWildcard
hint helps you define a set of implementation types that require instance creation control. You can use it to specify a wildcard to filter bindings by implementation name.
For more hints, see this page.
The following partial class will be generated:
partial class Composition
{
private readonly Composition _root;
private readonly Lock _lock;
private Dependency? _singletonDependency43;
[OrdinalAttribute(256)]
public Composition()
{
_root = this;
_lock = new Lock();
}
internal Composition(Composition parentScope)
{
_root = (parentScope ?? throw new ArgumentNullException(nameof(parentScope)))._root;
_lock = _root._lock;
}
public IService Root
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (_root._singletonDependency43 is null)
{
using (_lock.EnterScope())
{
if (_root._singletonDependency43 is null)
{
Dependency _singletonDependency43Temp;
_singletonDependency43Temp = new Dependency();
OnNewInstance<Dependency>(ref _singletonDependency43Temp, null, Lifetime.Singleton);
Thread.MemoryBarrier();
_root._singletonDependency43 = _singletonDependency43Temp;
}
}
}
Service transientService0 = new Service(_root._singletonDependency43);
OnNewInstance<Service>(ref transientService0, null, Lifetime.Transient);
return transientService0;
}
}
partial void OnNewInstance<T>(ref T value, object? tag, Lifetime lifetime);
}
Class diagram:
---
config:
class:
hideEmptyMembersBox: true
---
classDiagram
Service --|> IService
Dependency --|> IDependency
Composition ..> Service : IService Root
Service o-- "Singleton" Dependency : IDependency
namespace Pure.DI.UsageTests.Hints.OnNewInstanceWildcardHintScenario {
class Composition {
<<partial>>
+IService Root
}
class Dependency {
+Dependency()
}
class IDependency {
<<interface>>
}
class IService {
<<interface>>
}
class Service {
+Service(IDependency dependency)
}
}