@@ -29,6 +29,69 @@ public void CreatesScopeAndService()
29
29
Assert . Equal ( 1 , counter . DisposedCount ) ;
30
30
}
31
31
32
+ [ Fact ]
33
+ public async Task DisposeAsyncReleasesScopeAndService ( )
34
+ {
35
+ var services = new ServiceCollection ( ) ;
36
+ services . AddSingleton < Counter > ( ) ;
37
+ services . AddTransient < MyService > ( ) ;
38
+ var serviceProvider = services . BuildServiceProvider ( ) ;
39
+
40
+ var counter = serviceProvider . GetRequiredService < Counter > ( ) ;
41
+ var renderer = new TestRenderer ( serviceProvider ) ;
42
+ var component1 = ( MyOwningComponent ) renderer . InstantiateComponent < MyOwningComponent > ( ) ;
43
+
44
+ Assert . NotNull ( component1 . MyService ) ;
45
+ Assert . Equal ( 1 , counter . CreatedCount ) ;
46
+ Assert . Equal ( 0 , counter . DisposedCount ) ;
47
+ Assert . False ( component1 . IsDisposedPublic ) ;
48
+
49
+ await ( ( IAsyncDisposable ) component1 ) . DisposeAsync ( ) ;
50
+ Assert . Equal ( 1 , counter . CreatedCount ) ;
51
+ Assert . Equal ( 1 , counter . DisposedCount ) ;
52
+ Assert . True ( component1 . IsDisposedPublic ) ;
53
+ }
54
+
55
+ [ Fact ]
56
+ public void ThrowsWhenAccessingScopedServicesAfterDispose ( )
57
+ {
58
+ var services = new ServiceCollection ( ) ;
59
+ services . AddSingleton < Counter > ( ) ;
60
+ services . AddTransient < MyService > ( ) ;
61
+ var serviceProvider = services . BuildServiceProvider ( ) ;
62
+
63
+ var renderer = new TestRenderer ( serviceProvider ) ;
64
+ var component1 = ( MyOwningComponent ) renderer . InstantiateComponent < MyOwningComponent > ( ) ;
65
+
66
+ // Access service first to create scope
67
+ var service = component1 . MyService ;
68
+
69
+ ( ( IDisposable ) component1 ) . Dispose ( ) ;
70
+
71
+ // Should throw when trying to access services after disposal
72
+ Assert . Throws < ObjectDisposedException > ( ( ) => component1 . MyService ) ;
73
+ }
74
+
75
+ [ Fact ]
76
+ public async Task ThrowsWhenAccessingScopedServicesAfterDisposeAsync ( )
77
+ {
78
+ var services = new ServiceCollection ( ) ;
79
+ services . AddSingleton < Counter > ( ) ;
80
+ services . AddTransient < MyService > ( ) ;
81
+ var serviceProvider = services . BuildServiceProvider ( ) ;
82
+
83
+ var renderer = new TestRenderer ( serviceProvider ) ;
84
+ var component1 = ( MyOwningComponent ) renderer . InstantiateComponent < MyOwningComponent > ( ) ;
85
+
86
+ // Access service first to create scope
87
+ var service = component1 . MyService ;
88
+
89
+ await ( ( IAsyncDisposable ) component1 ) . DisposeAsync ( ) ;
90
+
91
+ // Should throw when trying to access services after disposal
92
+ Assert . Throws < ObjectDisposedException > ( ( ) => component1 . MyService ) ;
93
+ }
94
+
32
95
private class Counter
33
96
{
34
97
public int CreatedCount { get ; set ; }
@@ -51,5 +114,8 @@ public MyService(Counter counter)
51
114
private class MyOwningComponent : OwningComponentBase < MyService >
52
115
{
53
116
public MyService MyService => Service ;
117
+
118
+ // Expose IsDisposed for testing
119
+ public bool IsDisposedPublic => IsDisposed ;
54
120
}
55
121
}
0 commit comments