Open Sputnik24 opened 1 year ago
Thanks for filing this - it's an interesting edge case. Container creation depends on the IStartable
things running, but if those fail, disposal isn't executed. Hmmm.
I'm guessing we haven't handled this because, in general, if an application's container doesn't successfully build, the application itself is largely unusable. There's no "recovering," so the process terminates and the various finalizers are left to do their work to clean things up rather than actively calling Dispose()
.
Which isn't to say we shouldn't handle it, just that I can see why no one thought of that as a thing to test.
From stackoverflow: https://stackoverflow.com/questions/76991305/autofac-dispose-of-created-services-not-called-when-exception-is-thrown-by-late
I have the following, minimal example to reproduce an issue of my real life application:
and a console application:
From dependency chain ServiceB is a dependency of ServiceA and, therfore, is instanciated first on Build(). During Start() of ServiceA, Connect() on ServiceB is called which throws an Exception. The Exception is forwared to Build() which fails and the container is not created.
My expectation reading Autofac docs
would be, that Dipose() on created ServiceB is called. This is not the case. ServiceB lives somewhere in my application and I cannot dispose it as IContainer was not created.
ChatGPT suggest to catch the exception and call Dispose() on IContainer later. This would mean, I need to check if Connect() on ServiceB was successfull (property bool IsConnected) and if not, I call Dispose().
Of course, this would solve my issue. But again, my expecation was, that Autofac is handling this for me via LifetimeScope.