Skip to content

Latest commit

 

History

History
191 lines (160 loc) · 4.92 KB

File metadata and controls

191 lines (160 loc) · 4.92 KB

OnNewInstance wildcard hint

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
dotnet --list-sdk
  • Create a net10.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
{
#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()
		}
	}
Loading