Injecting WeakReference<T> lets a service hold a dependency without keeping it alive — useful for large, recreatable objects such as caches. Bind the underlying type as usual and request WeakReference<T>; the consumer then calls TryGetTarget, which returns false once the object has been garbage-collected.
using Shouldly;
using Pure.DI;
DI.Setup(nameof(Composition))
.Bind<ILargeCache>().To<LargeCache>()
.Bind<IService>().To<Service>()
// Composition root
.Root<IService>("MyService");
var composition = new Composition();
var service = composition.MyService;
// Represents a large memory object (e.g., a cache of images or large datasets)
interface ILargeCache;
class LargeCache : ILargeCache;
interface IService;
class Service(WeakReference<ILargeCache> cache) : IService
{
public ILargeCache? Cache =>
// Tries to retrieve the target object from the WeakReference.
// If the object has been collected by the GC, it returns null.
cache.TryGetTarget(out var value)
? value
: null;
}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 runNote
WeakReference<T> is useful for caching scenarios where you want to allow garbage collection when memory is constrained.
The injected reference does not keep the target alive, so the consumer has to handle TryGetTarget returning false every time and recreate the value — Service.Cache returns null for that case. That makes the consumer's own code the cache, not the composition.
A weak reference is only useful when something else holds the target strongly; if the dependency is transient and nobody else keeps it, it can be collected immediately after construction. Bind the target as Singleton (or hold it elsewhere) when the reference is expected to survive.
Tip
Prefer a normal reference when the lifetime of the object is known, and reach for WeakReference<T> only for optional, recreatable and genuinely large data.
The following partial class will be generated
partial class Composition
{
public IService MyService
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new Service(new WeakReference<ILargeCache>(new LargeCache()));
}
}
}Class diagram:
---
config:
class:
hideEmptyMembersBox: true
---
classDiagram
LargeCache --|> ILargeCache
Service --|> IService
Composition ..> Service : IService MyService
Service *-- WeakReferenceᐸILargeCacheᐳ : WeakReferenceᐸILargeCacheᐳ
WeakReferenceᐸILargeCacheᐳ *-- LargeCache : ILargeCache
namespace Pure.DI.UsageTests.BCL.WeakReferenceScenario {
class Composition {
<<partial>>
+IService MyService
}
class ILargeCache {
<<interface>>
}
class IService {
<<interface>>
}
class LargeCache {
<<class>>
+LargeCache()
}
class Service {
<<class>>
+Service(WeakReferenceᐸILargeCacheᐳ cache)
}
}
namespace System {
class WeakReferenceᐸILargeCacheᐳ {
<<class>>
+WeakReference(ILargeCache target)
}
}