Disposing dbContext with dependency injection
Hi!
I am developing an Avalonia UI app. I am displaying there some data, which is stored in the sqlite database. The data - rows in that matter - can be deleted or added, but once they are there - they are not modified (at least for now ;)).
I have a factory which gets data from db and then creates a view model passing there the data (and few other things). The factory itself I've registered in service container as a singleton and dbContext as a transient. dbContext is injected into the factory. As I am not tracking entities changes and not adding or deleting data in that place, I've configured the context with
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
.
I have not encountered any issues so far, however I am concerned about proper dbContext disposing. If a factory is singleton, even when dbContext is transient, once it's injected is still there, right? The view model can be created few times during app lifetime, rows can be added/removed in the meantime.
Can I leave it as it is or should I do smth about it? Eg. instead of injecting dbContext itself I can create and inject another factory which will instantiate dbContext via constructor each time needed, or maybe you can suggest other solutions?
Any help appreciated 😉8 Replies
a transient injected into a singleton will indeed be "captured" and hoisted up to a singleton lifecycle
dbcontexts are intended to be short-lived, on the scale of a single method call or a http request
so I would create and dispose your client on a short enough timeframe to get the data you need each time you need it
for that, you can either create your dbcontexts manually with new(), or use the dedicated dbcontextfactory (though that may be asp.net core only, I forget)
IDbContextFactory Interface (Microsoft.EntityFrameworkCore)
Defines a factory for creating DbContext instances.
It's not. I use that approach in an Avalonia app. eg.
that seems totally fine to me
though I think you can use "await using" since it's an async method
And for the DI configuration side (though you don't need NodaTime):
I'm pretty sure
await using
wasn't a feature when this was made.fair enough 🙂
Oh, maybe not.
await using
is a lot older than I thought. C# 8.i rarely remember to use it when my ide isn't configured to lint about it
since it's rarely intuitive what classes have implemented iasyncdisposable over plain idisposable
in my experience