enumerable.md

July 3, 2026 · View on GitHub

Enumerable

Specifying IEnumerable<T> as the injection type lets you inject instances of all bindings that implement type T in a lazy fashion - the instances will be provided one by one, in order corresponding to the sequence of bindings.

using Shouldly;
using Pure.DI;
using System.Collections.Immutable;

DI.Setup(nameof(Composition))
    .Bind<IMessageSender>().To<EmailSender>()
    .Bind<IMessageSender>("sms").To<SmsSender>()
    .Bind<INotificationService>().To<NotificationService>()

    // Composition root
    .Root<INotificationService>("NotificationService");

var composition = new Composition();
var notificationService = composition.NotificationService;
notificationService.Senders.Length.ShouldBe(2);
notificationService.Senders[0].ShouldBeOfType<EmailSender>();
notificationService.Senders[1].ShouldBeOfType<SmsSender>();

notificationService.Notify("Hello World");

interface IMessageSender
{
    void Send(string message);
}

class EmailSender : IMessageSender
{
    public void Send(string message)
    {
        // Sending email...
    }
}

class SmsSender : IMessageSender
{
    public void Send(string message)
    {
        // Sending SMS...
    }
}

interface INotificationService
{
    ImmutableArray<IMessageSender> Senders { get; }

    void Notify(string message);
}

class NotificationService(IEnumerable<IMessageSender> senders) : INotificationService
{
    public ImmutableArray<IMessageSender> Senders { get; }
        = [..senders];

    public void Notify(string message)
    {
        foreach (var sender in Senders)
        {
            sender.Send(message);
        }
    }
}
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

Note

IEnumerable provides lazy evaluation, making it efficient for scenarios where you may not need to enumerate all instances.

The following partial class will be generated
partial class Composition
{
  public INotificationService NotificationService
  {
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    get
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      IEnumerable<IMessageSender> EnumerationOf_perBlockIEnumerableIMessageSender()
      {
        yield return new EmailSender();
        yield return new SmsSender();
      }

      return new NotificationService(EnumerationOf_perBlockIEnumerableIMessageSender());
    }
  }
}

Class diagram:

---
 config:
  class:
   hideEmptyMembersBox: true
---
classDiagram
	EmailSender --|> IMessageSender
	SmsSender --|> IMessageSender : "sms"
	NotificationService --|> INotificationService
	Composition ..> NotificationService : INotificationService NotificationService
	NotificationService o-- "PerBlock" IEnumerableᐸIMessageSenderᐳ : IEnumerableᐸIMessageSenderᐳ
	IEnumerableᐸIMessageSenderᐳ *-- EmailSender : IMessageSender
	IEnumerableᐸIMessageSenderᐳ *-- SmsSender : "sms" IMessageSender
	namespace Pure.DI.UsageTests.BCL.EnumerableScenario {
		class Composition {
		<<partial>>
		+INotificationService NotificationService
		}
		class EmailSender {
				<<class>>
			+EmailSender()
		}
		class IMessageSender {
			<<interface>>
		}
		class INotificationService {
			<<interface>>
		}
		class NotificationService {
				<<class>>
			+NotificationService(IEnumerableᐸIMessageSenderᐳ senders)
		}
		class SmsSender {
				<<class>>
			+SmsSender()
		}
	}
	namespace System.Collections.Generic {
		class IEnumerableᐸIMessageSenderᐳ {
				<<interface>>
		}
	}

See also: