Revisit tracking transient services for disposal #456
Description
Tracking transient objects for disposal is a pretty bad practice and will almost always lead to memory leaks. Even if it's tracked in a scoped provider, it'll be kept around for longer than it needs to, at a minimum.
This is why containers like SimpleInjector and StructureMap (and probably others as well) don't track transient disposables. SimpleInjector even has a diagnostic warning about this.
In order to comply with the MS.Ext.DI specs, StructureMap had to introduce a way to opt-in to track transients for disposal, which sucks.
I've already seen several reports on severe memory leaks because of this in the wild. Here's the latest example: https://gitter.im/aspnet/Home?at=57ff6e91891a530163074f94
Hey guys ... anybody here that has some experience with the .NET Core DI implementation? I run into a memory leak because a type I registered with
services.AddTransient<IMyType, MyType>()
does not get garbage collected. With VS memory diagnostics I found out that aList<IDisposable>
within theServiceProvider
class holds references to all instances of it. So it might be a misconception about how it should work on my side ... but I think thatServiceProvider
should not hold references to types I registered as transient. Am I wrong about that?
I also suspect there are other, less severe memory leaks around, that people haven't noticed yet or worked around.
What can be done about this? The least breaking change I can see is add a Release
method somewhere that can be used to explicitly evict specific instances from tracking, but ideally, this behavior should be removed altogether and throw if a transient disposable is registered.
// @davidfowl @pakrym @tillig @alexmg @nblumhardt @seesharper @jeremydmiller @dotnetjunkie