You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The container constructed singletons and never disposed them, so anything
holding an unmanaged resource leaked for the process lifetime. It now owns
what it constructs: disposing the container disposes those instances in
reverse construction order, so a dependent is always disposed before the
dependency it was handed. Instances supplied through AddInstance belong to
the caller and are left alone.
Async disposal needs IAsyncDisposable, which netstandard2.0 cannot name.
Rather than take a dependency or add a second target framework, the
generator emits the disposer into the consuming assembly — which is
compiled against a framework that has the interface — and the container
stores it as a plain delegate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -158,6 +158,29 @@ var container = new DependencyContainerBuilder()
158
158
varuserRepo=container.Resolve<UserRepository>();
159
159
```
160
160
161
+
### Disposal
162
+
163
+
The container owns the lifetime of every singleton it **constructs**. Disposing the container disposes those singletons in **reverse construction order**, so a dependent is always disposed before the dependency it was handed:
164
+
165
+
```csharp
166
+
usingvarcontainer=newDependencyContainerBuilder()
167
+
.AddRegistry<GeneratedRegistry>()
168
+
.Build();
169
+
170
+
// ... resolve and use services ...
171
+
// leaving the scope disposes every singleton the container constructed
172
+
```
173
+
174
+
Instances you supply yourself — through `RegisterInstance` or `AddInstance` — are **not** the container's to dispose, and are left alone. Resolving from a disposed container throws `ObjectDisposedException`.
175
+
176
+
A singleton that implements `IAsyncDisposable` is disposed with `DisposeAsync`:
177
+
178
+
```csharp
179
+
awaitcontainer.DisposeAsync();
180
+
```
181
+
182
+
Calling the synchronous `Dispose()` throws if a singleton disposes *only* asynchronously; one that implements both interfaces is disposed synchronously. If a singleton throws while disposing, the rest are still disposed and the failures are reported together as an `AggregateException`.
Copy file name to clipboardExpand all lines: Source/Mal.SourceGeneratedDI.Abstractions/ReleaseNotes.txt
+8Lines changed: 8 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,11 @@
1
+
v2.1.0
2
+
- `DependencyContainer` now implements `IDisposable`: it disposes every singleton it constructed, in reverse construction order, so a dependent is disposed before the dependency it was given
3
+
- Instances registered through `AddInstance`/`RegisterInstance` belong to the caller and are never disposed
4
+
- Added `DependencyContainer.DisposeAsync()` for singletons that dispose asynchronously. `Dispose()` throws for a singleton that has no synchronous path; one that disposes both ways is disposed synchronously
5
+
- A singleton failing to dispose no longer strands the rest — all are attempted and the failures reported together as an `AggregateException`
6
+
- Resolving from a disposed container throws `ObjectDisposedException`
7
+
- Breaking: `IServiceRegistry` gains an `AddSingleton` overload taking an async disposer. This package targets netstandard2.0 and cannot name `IAsyncDisposable`, so the delegate is supplied by the caller — normally the generated registry, which is compiled against a framework that has the interface
8
+
1
9
v2.0.3
2
10
- IDependencyContainer now extends IServiceProvider for compatibility with generalized service consumers
0 commit comments