lazy.md
July 3, 2026 · View on GitHub
Lazy
Injecting Lazy<T> defers creation of a dependency until its Value property is first accessed, after which the same instance is returned every time. No extra setup is needed: bind the underlying type as usual and request Lazy<T> in the constructor.
using Shouldly;
using Pure.DI;
DI.Setup(nameof(Composition))
.Bind<IGraphicsEngine>().To<GraphicsEngine>()
.Bind<IWindow>().To<Window>()
// Composition root
.Root<IWindow>("Window");
var composition = new Composition();
var window = composition.Window;
// The graphics engine is created only when it is first accessed
window.Engine.ShouldBe(window.Engine);
interface IGraphicsEngine;
class GraphicsEngine : IGraphicsEngine;
interface IWindow
{
IGraphicsEngine Engine { get; }
}
class Window(Lazy<IGraphicsEngine> engine) : IWindow
{
public IGraphicsEngine Engine => engine.Value;
}
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 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
Note
Lazy
The following partial class will be generated
partial class Composition
{
public IWindow Window
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
Lazy<IGraphicsEngine> transientLazyIGraphicsEngine;
// Creates a lazy value factory
Func<IGraphicsEngine> perBlockFuncIGraphicsEngine = new Func<IGraphicsEngine>(
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
// Creates a deferred value
return new GraphicsEngine();
});
Func<IGraphicsEngine> localFactory = perBlockFuncIGraphicsEngine;
// Wraps it in Lazy<T>
transientLazyIGraphicsEngine = new Lazy<IGraphicsEngine>(localFactory, true);
return new Window(transientLazyIGraphicsEngine);
}
}
}
Class diagram:
---
config:
class:
hideEmptyMembersBox: true
---
classDiagram
GraphicsEngine --|> IGraphicsEngine
Window --|> IWindow
Composition ..> Window : IWindow Window
Window *-- LazyᐸIGraphicsEngineᐳ : LazyᐸIGraphicsEngineᐳ
LazyᐸIGraphicsEngineᐳ o-- "PerBlock" FuncᐸIGraphicsEngineᐳ : FuncᐸIGraphicsEngineᐳ
FuncᐸIGraphicsEngineᐳ *-- GraphicsEngine : IGraphicsEngine
namespace Pure.DI.UsageTests.BCL.LazyScenario {
class Composition {
<<partial>>
+IWindow Window
}
class GraphicsEngine {
<<class>>
+GraphicsEngine()
}
class IGraphicsEngine {
<<interface>>
}
class IWindow {
<<interface>>
}
class Window {
<<class>>
+Window(LazyᐸIGraphicsEngineᐳ engine)
}
}
namespace System {
class FuncᐸIGraphicsEngineᐳ {
<<delegate>>
}
class LazyᐸIGraphicsEngineᐳ {
<<class>>
}
}
See also: