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")
// Hints restrict the generation of the partial OnNewInstance method
// to only those types whose names match the specified wildcards.
// In this case, we want to track the creation of repositories and services.
.Hint(OnNewInstanceImplementationTypeNameWildcard, "*Repository")
.Hint(OnNewInstanceImplementationTypeNameWildcard, "*Service")
.Bind().As(Lifetime.Singleton).To<UserRepository>()
.Bind().To<OrderService>()
// This type will not be tracked because its name
// does not match the wildcards
.Bind().To<ConsoleLogger>()
.Root<IOrderService>("Root");
var log = new List<string>();
var composition = new Composition(log);
var service1 = composition.Root;
var service2 = composition.Root;
log.ShouldBe([
"UserRepository created",
"OrderService created",
"OrderService created"
]);
interface IRepository;
class UserRepository : IRepository
{
public override string ToString() => nameof(UserRepository);
}
interface ILogger;
class ConsoleLogger : ILogger
{
public override string ToString() => nameof(ConsoleLogger);
}
interface IOrderService
{
IRepository Repository { get; }
}
class OrderService(IRepository repository, ILogger logger) : IOrderService
{
public IRepository Repository { get; } = repository;
public ILogger Logger { get; } = logger;
public override string ToString() => nameof(OrderService);
}
internal partial class Composition(List<string> 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 10.0 or later installed
dotnet --list-sdk- Create a net10.0 (or later) console application
dotnet new console -n Sampledotnet 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 runThe 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
{
#if NET9_0_OR_GREATER
private readonly Lock _lock = new Lock();
#else
private readonly Object _lock = new Object();
#endif
private UserRepository? _singletonUserRepository62;
public IOrderService Root
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (_singletonUserRepository62 is null)
lock (_lock)
if (_singletonUserRepository62 is null)
{
UserRepository _singletonUserRepository62Temp;
_singletonUserRepository62Temp = new UserRepository();
OnNewInstance<UserRepository>(ref _singletonUserRepository62Temp, null, Lifetime.Singleton);
Thread.MemoryBarrier();
_singletonUserRepository62 = _singletonUserRepository62Temp;
}
var transientOrderService555 = new OrderService(_singletonUserRepository62, new ConsoleLogger());
OnNewInstance<OrderService>(ref transientOrderService555, null, Lifetime.Transient);
return transientOrderService555;
}
}
partial void OnNewInstance<T>(ref T value, object? tag, Lifetime lifetime);
}Class diagram:
---
config:
maxTextSize: 2147483647
maxEdges: 2147483647
class:
hideEmptyMembersBox: true
---
classDiagram
UserRepository --|> IRepository
OrderService --|> IOrderService
ConsoleLogger --|> ILogger
Composition ..> OrderService : IOrderService Root
OrderService o-- "Singleton" UserRepository : IRepository
OrderService *-- ConsoleLogger : ILogger
namespace Pure.DI.UsageTests.Hints.OnNewInstanceWildcardHintScenario {
class Composition {
<<partial>>
+IOrderService Root
}
class ConsoleLogger {
<<class>>
+ConsoleLogger()
}
class ILogger {
<<interface>>
}
class IOrderService {
<<interface>>
}
class IRepository {
<<interface>>
}
class OrderService {
<<class>>
+OrderService(IRepository repository, ILogger logger)
}
class UserRepository {
<<class>>
+UserRepository()
}
}