async-enumerable.md
July 3, 2026 ¡ View on GitHub
Async Enumerable
Specifying IAsyncEnumerable<T> as the injection type allows instances of all bindings implementing type T to be injected in an asynchronous-lazy manner - the instances will be provided one at a time, in an order corresponding to the sequence of the bindings.
using Shouldly;
using Pure.DI;
DI.Setup(nameof(Composition))
.Bind<IHealthCheck>().To<MemoryCheck>()
.Bind<IHealthCheck>("External").To<ExternalServiceCheck>()
.Bind<IHealthService>().To<HealthService>()
// Composition root
.Root<IHealthService>("HealthService");
var composition = new Composition();
var healthService = composition.HealthService;
var checks = await healthService.GetChecksAsync();
checks[0].ShouldBeOfType<MemoryCheck>();
checks[1].ShouldBeOfType<ExternalServiceCheck>();
interface IHealthCheck;
class MemoryCheck : IHealthCheck;
class ExternalServiceCheck : IHealthCheck;
interface IHealthService
{
Task<IReadOnlyList<IHealthCheck>> GetChecksAsync();
}
class HealthService(IAsyncEnumerable<IHealthCheck> checks) : IHealthService
{
public async Task<IReadOnlyList<IHealthCheck>> GetChecksAsync()
{
var results = new List<IHealthCheck>();
await foreach (var check in checks)
{
results.Add(check);
}
return results;
}
}
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
IAsyncEnumerable
The following partial class will be generated
partial class Composition
{
public IHealthService HealthService
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
async IAsyncEnumerable<IHealthCheck> EnumerationOf_transientIAsyncEnumerableIHealthCheck()
{
yield return new MemoryCheck();
yield return new ExternalServiceCheck();
await Task.CompletedTask;
}
return new HealthService(EnumerationOf_transientIAsyncEnumerableIHealthCheck());
}
}
}
Class diagram:
---
config:
class:
hideEmptyMembersBox: true
---
classDiagram
MemoryCheck --|> IHealthCheck
ExternalServiceCheck --|> IHealthCheck : "External"
HealthService --|> IHealthService
Composition ..> HealthService : IHealthService HealthService
HealthService *-- IAsyncEnumerableá¸IHealthCheckáł : IAsyncEnumerableá¸IHealthCheckáł
IAsyncEnumerableá¸IHealthCheckáł *-- MemoryCheck : IHealthCheck
IAsyncEnumerableá¸IHealthCheckáł *-- ExternalServiceCheck : "External" IHealthCheck
namespace Pure.DI.UsageTests.BCL.AsyncEnumerableScenario {
class Composition {
<<partial>>
+IHealthService HealthService
}
class ExternalServiceCheck {
<<class>>
+ExternalServiceCheck()
}
class HealthService {
<<class>>
+HealthService(IAsyncEnumerableá¸IHealthCheckáł checks)
}
class IHealthCheck {
<<interface>>
}
class IHealthService {
<<interface>>
}
class MemoryCheck {
<<class>>
+MemoryCheck()
}
}
namespace System.Collections.Generic {
class IAsyncEnumerableá¸IHealthCheckáł {
<<interface>>
}
}
See also: