Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds extension method to create service scope that implements IAsyncDisposable. #51840

Merged
merged 8 commits into from
Apr 28, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ public partial class ActivatorUtilitiesConstructorAttribute : System.Attribute
{
public ActivatorUtilitiesConstructorAttribute() { }
}
public struct AsyncServiceScope : Microsoft.Extensions.DependencyInjection.IServiceScope, System.IAsyncDisposable
{
public AsyncServiceScope(Microsoft.Extensions.DependencyInjection.IServiceScope serviceScope)
{
maryamariyan marked this conversation as resolved.
Show resolved Hide resolved
}
public System.IServiceProvider ServiceProvider { get { throw null; } }
public void Dispose() { }
public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
}
public partial interface IServiceCollection : System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>, System.Collections.Generic.IList<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>, System.Collections.IEnumerable
{
}
Expand Down Expand Up @@ -106,6 +115,7 @@ public enum ServiceLifetime
}
public static partial class ServiceProviderServiceExtensions
{
public static Microsoft.Extensions.DependencyInjection.AsyncServiceScope CreateAsyncScope(this System.IServiceProvider provider) { throw null; }
public static Microsoft.Extensions.DependencyInjection.IServiceScope CreateScope(this System.IServiceProvider provider) { throw null; }
public static object GetRequiredService(this System.IServiceProvider provider, System.Type serviceType) { throw null; }
public static T GetRequiredService<T>(this System.IServiceProvider provider) where T : notnull { throw null; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netstandard2.1;netstandard2.0;net461</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="Microsoft.Extensions.DependencyInjection.Abstractions.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMembersAttribute.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMemberTypes.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or
$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">
<PackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Bcl.AsyncInterfaces\src\Microsoft.Bcl.AsyncInterfaces.csproj" />
bjorkstromm marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading.Tasks;

namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// A <see cref="IServiceScope" /> implementation that implements <see cref="IAsyncDisposable" />.
/// </summary>
public struct AsyncServiceScope : IServiceScope, IAsyncDisposable
bjorkstromm marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly IServiceScope _serviceScope;

/// <summary>
/// Initializes a new instance of the <see cref="AsyncServiceScope"/> struct.
/// Wraps an instance of <see cref="IServiceScope" />.
/// <param name="serviceScope">The <see cref="IServiceScope"/> instance to wrap.</param>
/// </summary>
public AsyncServiceScope(IServiceScope serviceScope)
{
if (serviceScope is null)
{
throw new ArgumentNullException(nameof(serviceScope));
}

_serviceScope = serviceScope;
bjorkstromm marked this conversation as resolved.
Show resolved Hide resolved
}

/// <inheritdoc />
public IServiceProvider ServiceProvider => _serviceScope.ServiceProvider;

/// <inheritdoc />
public void Dispose()
{
_serviceScope.Dispose();
}

/// <inheritdoc />
public ValueTask DisposeAsync()
{
if (_serviceScope is IAsyncDisposable ad)
{
return ad.DisposeAsync();
}
_serviceScope.Dispose();
return default;
bjorkstromm marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netstandard2.1;netstandard2.0;net461</TargetFrameworks>
<EnableDefaultItems>true</EnableDefaultItems>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand All @@ -14,4 +14,10 @@
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or
$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">
<PackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Bcl.AsyncInterfaces\src\Microsoft.Bcl.AsyncInterfaces.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,15 @@ public static IServiceScope CreateScope(this IServiceProvider provider)
{
return provider.GetRequiredService<IServiceScopeFactory>().CreateScope();
}

/// <summary>
/// Creates a new <see cref="AsyncServiceScope"/> that can be used to resolve scoped services.
/// </summary>
/// <param name="provider">The <see cref="IServiceProvider"/> to create the scope from.</param>
/// <returns>A <see cref="AsyncServiceScope"/> that can be used to resolve scoped services.</returns>
public static AsyncServiceScope CreateAsyncScope(this IServiceProvider provider)
{
return new AsyncServiceScope(provider.CreateScope());
}
}
}