Home > front end >  Context Lifetime on a WinForms app .Net6 with Dependency Injection
Context Lifetime on a WinForms app .Net6 with Dependency Injection

Time:11-15

I am having some issues with context lifetime on my .NetCore 6 win forms application. In summary, I have a button that when clicked calls a repository which then retrieves a record from my DB and displays one value from that record in a text field. This works ok until that value changes in the database. Further clicks of the button continue to display the old value.

This is how I register my context in the winforms app

services.AddDbContext<MyContext>(b => b.UseSqlServer(connectionString));

I then register my services like this:

services.AddScoped<IMyRepo, MyRepo>();

I guess this is an issue where the form is long running and never disposes the context, hence why the result is always the same until the form is closed and reopened with a fresh context.

I am using this in my repo to force a new result each time, however is seems like a bit of a mission to do this for every request to the DB I make...

_entities.Entry(log).Reload();

Is there a cleaner way I can do this without having to do the reload?

CodePudding user response:

Honestly, I wouldn't use the MS IoC AddDbContext for WinForms/WPF. There probably is a way to have it play nice with some form of lifetime scope, but I'm honestly not aware of one. I don't use it for web projects either, simply because it scopes the DbContext to the request and I like to have a bit more control over the lifetime of the DbContext in some situations. (Dealing with poisoned contexts for instance)

For web and WPF I've used a Unit of Work pattern called the DbContextScope to manage the DbContext and relationship with the Repositories. The idea being that the consumers use an injected DBContextScopeFactory to create a DbContextScope (wrapping one or more DbContext instances) and the Repositories accept an injected DbContexScopeLocator to gain access to a requested DbContextScope.

The original EF6 implementation was by Medhi El Gueddari (https://github.com/mehdime/DbContextScope || https://www.nuget.org/packages/Mehdime.Entity)

For EF Core 6: (https://www.nuget.org/packages/Zejji.DbContextScope.EFCore6)

Alternatively if the scope of a DbContext can be contained within the repository calls themselves (tracked entities don't need to be passed outside of the repository) then you could also just use an injected DbContextFactory class to provide DbContext instances on demand. The advantage of a UoW pattern like above is that you have control over the scope the DbContext instance(s) live so multiple operations can be committed together or rolled back. The DbContext instance is available between multiple repositories if needed.

  • Related