Skip to content

Instantly share code, notes, and snippets.

@emanuelefirmani
Created July 21, 2025 15:51
Show Gist options
  • Select an option

  • Save emanuelefirmani/dbfb40d23d88ec8a8ea328cb4e10e12b to your computer and use it in GitHub Desktop.

Select an option

Save emanuelefirmani/dbfb40d23d88ec8a8ea328cb4e10e12b to your computer and use it in GitHub Desktop.
Owned
internal class Owned<T>(IServiceScopeFactory factory) : IDisposable where T : notnull
{
private IServiceScope? _scope;
internal T Value
{
_scope ??= factory.CreateScope();
return _scope.ServiceProvider.GetRequiredService<T>();
}
public void Dispose()
{
_scope?.Dispose();
}
}
public class OwnedTest : IDisposable, IAsyncDisposable
{
private readonly ServiceProvider _provider;
internal sealed class TestClass;
public OwnedTest()
{
var services = new ServiceCollection();
services.AddTransient(typeof(Owned<>));
services.AddScoped<TestClass>();
_provider = services.BuildServiceProvider();
}
[Fact]
void Scoped_reuses_scope()
{
using var owned = _provider.GetRequiredService<Owned<TestClass>>();
var instance1 = owned.Value();
var instance2 = owned.Value();
Assert.Same(instance1, instance2);
}
[Fact]
void two_Scoped_do_not_share_scope()
{
using var o1 = _provider.GetRequiredService<Owned<TestClass>>();
using var o2 = _provider.GetRequiredService<Owned<TestClass>>();
var instance1 = o1.Value();
var instance2 = o2.Value();
Assert.NotSame(instance1, instance2);
}
public void Dispose()
{
_provider.Dispose();
}
public async ValueTask DisposeAsync()
{
await _provider.DisposeAsync();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment