Skip to content

v7.1.1

Latest

Choose a tag to compare

@seesharper seesharper released this 30 Sep 13:50
b943de2

Change Log

v7.1.1 (09/30/2026)

Full Changelog

Merged Pull Requests

Synchronize CanGetInstance with delegate creation (09/25/2026) #616 (seesharper)

Fixes #614

Problem

CreateDelegate holds lockObject while building emit methods, but CanGetInstance walks the same GetEmitMethod → CreateEmitMethodForUnknownService path without the lock. That path can register closed generic services, appending to the List<ServiceRegistration> / List<EmitMethodInfo> values in allRegistrations / allEmitters while another thread enumerates them in CreateEmitMethodForEnumerableServiceServiceRequest:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Linq.Enumerable+SelectManySingleSelectorIterator...
   at LightInject.ServiceContainer.CreateEmitMethodForEnumerableServiceServiceRequest(...)

With LightInject.Microsoft.DependencyInjection, CanGetInstance backs IServiceProviderIsService, which ActivatorUtilities (Hangfire, MVC, etc.) calls at runtime, so this shows up under production load.

Fix

Take lockObject in CanGetInstance. Monitor is reentrant, so nested calls from within CreateDelegate are unaffected.

Tests

Issue614 runs CanGetInstance and GetInstance concurrently for many open generic enumerables with MS compatibility enabled. It fails consistently on master (corrupted lists from concurrent List.Add) and passes with the fix. Full suite passes (1562 tests).

A separate, pre-existing issue where closed generic enumerables accumulate duplicate items in MS compatibility mode will be addressed in a follow-up PR.

🤖 Generated with Claude Code
Only close open generic registrations once per closed service type (09/25/2026) #617 (seesharper)

Follow-up to #616 (found while investigating #614).

Problem

With EnableMicrosoftCompatibility, CreateEmitMethodForEnumerableServiceServiceRequest closes all open generic registrations and appends them to allEmitters every time an enumerable emit method is created for a closed generic service type. Emit methods are created more than once for the same type (as a dependency, as a root service, via CanGetInstance), so items accumulate:

container.Register(typeof(IBehavior<>), typeof(FirstBehavior<>));
container.Register(typeof(IBehavior<>), typeof(SecondBehavior<>));

container.GetInstance<Handler<int>>();                 // IEnumerable<IBehavior<int>> -> 2 items
container.GetInstance<IEnumerable<IBehavior<int>>>();  // 4 items (expected 2)

Calling CanGetInstance first gives 4 and 6. A closed generic that was first registered through a single-service request (CreateEmitMethodBasedOnClosedGenericServiceRequest) was also added again by the enumerable path. For MediatR users this means pipeline behaviors can run multiple times.

Without Microsoft compatibility the problem was masked because emitters are stored per service name (TryAdd).

Fix

Track, per closed generic service type, which open generic registrations (identified by their unique RegistrationOrder) have already been closed, and skip them on subsequent requests. The single-service path marks its registration too, when the closed registration uses the same service name as the open one.

Tests

  • ClosedGenericEnumerableTests covers resolving the enumerable multiple times, after CanGetInstance, and after a single-service resolve, with and without Microsoft compatibility. The MS-compat cases fail on master and pass with the fix.
  • Full suite passes (1567 tests).
  • LightInject.Microsoft.DependencyInjection's test suite (including the MS.DI specification tests) passes against this build (266 tests).

🤖 Generated with Claude Code
Bump version to 7.1.1 (09/30/2026) #619 (seesharper)

Bumps the version to 7.1.1.

Includes:

  • #616 Synchronize CanGetInstance with delegate creation (fixes #614)
  • #617 Only close open generic registrations once per closed service type

🤖 Generated with Claude Code

Closed Issues

  • Keyed Services Support? 🤔 (08/26/2026) #596 (Mike-E-angelo)
  • Collection was modified exception when resolving open generics (09/25/2026) #614 (ArnaudB88)
  • Fix keyed open-generic registration support in LightInject.Microsoft.DependencyInjection. (09/24/2026) #615 (TS-DanielH)
  • LightInject fails to start an NServiceBus 10 endpoint registered with a string endpoint identifier. (09/28/2026) #618 (TS-DanielH)