Skip to content

Commit 993169f

Browse files
committed
Allowed multiple Simple Injector containers, coupled to a single service collection, to be disposed on shutdown. Fixes #32
1 parent c310f12 commit 993169f

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

src/SimpleInjector.Integration.AspNetCore/SimpleInjectorAddOptionsAspNetCoreExtensions.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace SimpleInjector
55
{
66
using System;
7+
using System.Linq;
78
using Microsoft.AspNetCore.Http;
89
using Microsoft.Extensions.DependencyInjection;
910
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -116,19 +117,24 @@ private static IServiceProviderAccessor CreateServiceProviderAccessor(
116117
private static void AddContainerDisposalOnShutdown(
117118
SimpleInjectorAddOptions options, IServiceCollection services)
118119
{
119-
// DisposeContainerWithServiceProvider only support synchronous disposal, so we replace this with an
120+
// The core implementation only support synchronous disposal, so we replace this with an
120121
// ASP.NET Core-specific implementation that actually supports asynchronous disposal. This can be done
121122
// with an IHostedService implementation.
122-
services.AddSingleton<ContainerDisposeWrapper>();
123+
124+
// #32. By calling AddSingleton<T>(_ => new ...) we allow multiple wrappers to be registered, in case the
125+
// user want to couple multiple container instances to one MS.DI instance. This isn't possible when calling
126+
// AddSingleton<T>().
127+
var wrapper = new ContainerDisposeWrapper(options.Container);
128+
services.AddSingleton(_ => wrapper);
123129

124130
options.Container.Options.ContainerLocking += (_, __) =>
125131
{
126132
// If there's no IServiceProvider, the property will throw, which is something we want to do at this
127133
// point, not later on, when an unregistered type is resolved.
128134
IServiceProvider provider = options.ApplicationServices;
129135

130-
// In order for the wrapper to get disposed of, it needs to be resolved once.
131-
provider.GetRequiredService<ContainerDisposeWrapper>();
136+
// In order for the wrappers to get disposed of, they needs to be resolved once.
137+
provider.GetServices<ContainerDisposeWrapper>().ToArray();
132138
};
133139

134140
// By setting the property to false, we prevent the AddSimpleInjector method from adding its own shutdown

src/SimpleInjector.Integration.ServiceCollection/SimpleInjectorServiceCollectionExtensions.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ namespace SimpleInjector
2222
/// </summary>
2323
public static class SimpleInjectorServiceCollectionExtensions
2424
{
25-
private static readonly object AddOptionsKey = new object();
26-
private static readonly object AddLoggingKey = new object();
27-
private static readonly object AddLocalizationKey = new object();
25+
private static readonly object AddOptionsKey = new();
26+
private static readonly object AddLoggingKey = new();
27+
private static readonly object AddLocalizationKey = new();
2828

2929
/// <summary>
3030
/// Sets up the basic configuration that allows Simple Injector to be used in frameworks that require
@@ -457,17 +457,20 @@ private static void AddContainerDisposalOnShutdown(
457457
// #32. By calling AddSingleton<T>(_ => new ...) we allow multiple wrappers to be registered, in case the
458458
// user want to couple multiple container instances to one MS.DI instance. This isn't possible when calling
459459
// AddSingleton<T>().
460-
services.AddSingleton(_ => new ContainerDisposeWrapper(options.Container));
460+
var wrapper = new ContainerDisposeWrapper(options.Container);
461+
services.AddSingleton(_ => wrapper);
461462

462463
options.Container.Options.ContainerLocking += (_, __) =>
463464
{
464465
// If there's no IServiceProvider, the property will throw, which is something we want to do
465466
// at this point, not later on, when an unregistered type is resolved.
466467
IServiceProvider provider = options.ApplicationServices;
467468

468-
// In order for the wrapper to get disposed of, it needs to be resolved once.
469-
var wrapper = provider.GetRequiredService<ContainerDisposeWrapper>();
470-
wrapper.FrameworkProviderType = provider.GetType();
469+
// In order for the wrappers to get disposed of, they needs to be resolved once.
470+
foreach (var wrapper in provider.GetServices<ContainerDisposeWrapper>())
471+
{
472+
wrapper.FrameworkProviderType = provider.GetType();
473+
}
471474
};
472475
}
473476

0 commit comments

Comments
 (0)