Skip to content

Commit e72f4b3

Browse files
authored
Implement IAsyncDisposable on CompositeDisposableServiceProvider
This allows the service provider wrapper to be asynchronously dispose from the generated `app.RunAsync()` method. This method already checks if the provided `IServiceProvider` implements `IAsyncDisposable`. This ensures `ToConsoleAppBuilder` always correctly disposes too.
1 parent 92c637d commit e72f4b3

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

src/ConsoleAppFramework/Emitter.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ public void EmitAsConsoleAppBuilder(SourceBuilder sb, DllReference dllReference)
838838
internal static class ConsoleAppHostBuilderExtensions
839839
{
840840
class CompositeDisposableServiceProvider(IDisposable host, IServiceProvider serviceServiceProvider, IDisposable scope, IServiceProvider serviceProvider)
841-
: IServiceProvider, IKeyedServiceProvider, IDisposable
841+
: IServiceProvider, IKeyedServiceProvider, IDisposable, IAsyncDisposable
842842
{
843843
public object? GetService(Type serviceType)
844844
{
@@ -868,6 +868,25 @@ public void Dispose()
868868
}
869869
host.Dispose();
870870
}
871+
872+
public async ValueTask DisposeAsync()
873+
{
874+
await CastAndDispose(host);
875+
await CastAndDispose(scope);
876+
await CastAndDispose(serviceProvider);
877+
await CastAndDispose(serviceServiceProvider);
878+
GC.SuppressFinalize(this);
879+
880+
return;
881+
882+
static async ValueTask CastAndDispose<T>(T resource)
883+
{
884+
if (resource is IAsyncDisposable resourceAsyncDisposable)
885+
await resourceAsyncDisposable.DisposeAsync();
886+
else if (resource is IDisposable resourceDisposable)
887+
resourceDisposable.Dispose();
888+
}
889+
}
871890
}
872891
873892
internal static ConsoleApp.ConsoleAppBuilder ToConsoleAppBuilder(this IHostBuilder hostBuilder)

0 commit comments

Comments
 (0)