Context Lifetime on a WinForms app .Net6 with Dependency Injection - winforms

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?

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

DTOs and object graphs

I'm making an Angular2 SPA with a webAPI REST service that exposes an EntityFramework model.
The quickest way to get going is to load up a big object graph in a single controller action and pass out a big blob of JSON to the client, which can then split it up as it walks the object graph.
Is it considered better practice to build API actions for each object in the object graph and have the JS client pull the graph piecemeal as required?
The piecemeal approach requires many more controllers and actions and, correspondingly, angular services, i.e., more work! Do I need to just grasp the nettle and get on with it?
Actually it depends whether your are using Entity Framework in connected scenarios or in disconnected scenarios. Regarding your case, you are using Entity framework in disconnected scenarios, which mean that DBContext doesn't attach to object graph all the time, because you get the data from database, send it to the client and then close the context. For me, I would recommend to use divide your controllers and actions for each POCO or DTO because this will help you to maintain and attach each object individually rather than maintain the whole object graph at once. The problem will start to appear when you start editing or manipulating your entities because in disconnected scenarios you never know which object has been edited or deleted or added in a big object graph. However, you should maintain and manipulate each change in client side directly to the sever to reflect that update.
I don't know if this answers your question, but if you need any further explanation or code sample. please let me know.
I think you have to make one backend action for one angular2 page-level component. User shouldn't wait for extra data loads, only data that needed on this page.

Entity Framework Context lifetime

I have a WPF desktop app that using EF orm for mapping. My app have several pages
and each page has several windows. EF context is created per form. Pages in app using stateless entity only to show data the user.
My problem is that a page should update an entity for a single task and for this reason there should be a context living on this page. Therefore where I open window on this page for update other entities, there are 2 contexts active on this page.
How I can prevent this condition?
Create a new class "ClientRepository" in your project. This class will contain all entity framework access logic your client has.
Use this class in all your windows and pages.
If you configure this class to behave as singleton, you will only have one entity framework context.
Ideally this can be done using a DI framework like Microsoft Unit or Ninject, but of course you can also do it manually.
Singltons?
You might ask yourself, whether its a good idea to you singletons here.
I had a similar question once and thus asked Brian Noyes (Microsoft MVP) on a "MVVM" course on the pluralsight website.
In his response he wrote: "...most of my client services are Singletons anyway and live for the life of the app."
So, for a client service, its ok to have a singleton.

Angular ui-router nested views don't refresh data retrieved by Angular Services

I have a nontrivial Angular SPA that uses ui-router to manage multiple views, many of which are visible at the same time. I need models to be visible across controllers, so I have services written that allow me to have controllers pull down fresh copies of model data that has been updated.
I apologize in advance for the length of the question, but I will state the problem then state what I have done to address issues I'm sure others in the Angular community have struggled with.
I believe my problem is not understanding the lifecycle of controllers / views, because I get behavior where a controller initializes correctly the first time I go there, but then seems to never run again, even when I navigate to it using something like $state.go("state name").
In one view (contrived example), I show a summary of information about a customer, and in another view I allow a user to update that customer's more detailed profile. I want a user to edit, say, the customer last name in the detailed view, and have the summary view automatically recognize the change and display it.
I have a fiddle that shows 3 views and a simple password changing Service. The flow goes like this:
You can see each view gets initialized and displays the initial password retrieved from the service. All views are in sync with the DataService.
The middle view allows you to enter a new password and change the one stored in the service. Console logging confirms that the service picks up the new password just like you would expect.
(odd behavior #1) When the DataService receives the new password, I would expect the other 2 views (top and bottom) to display the new one. They don't... they still display the initial password.
There is a button to allow a user to go to another state via $state.go("state name") (a child state of the original) which also retrieves the password and displays it. This works the first time (see #5). Now the top view shows the outdated password, the middle view shows the new one, and the bottom one shows the new one as well. This seems normal, since the new view is invoked after the DataService contains a new password value.
(odd behavior #2) If I click back in the middle view and change the password again, and click the button to change states again, the bottom view (which updated just fine in step #4) no longer updates its copy of the password. Now all 3 views show different passwords, even though I am using a single service to pass values between controllers as suggested pretty much everywhere you look for Angular best practices.
Some possible solutions:
Tim Kindberg has an excellent slideshow here that seems to recommend using ui-router's state heirarchy to "pass" data among views that need to pick up values from other views. For a smaller-scale app I think I would settle on this, but I expect our application to have 30+ views displaying data from over 100 REST endpoints. I don't feel comfortable maintaining an application where all the data is being shared by a complex inheiritance tree. Especially using a routing framework that is at version 0.2.8.
I can use events to have controllers listen for changes in the data model. This actually works well. To accommodate performance concerns, I am using $rootScope.emit() and a $scope.$onRootScope('event name') decorator I found on here. With this approach I am less concerned about event performance than I am about wiring this huge app with a bunch of event listeners tying everything together. There is a question about the wisdom of wiring a large app using angular events here.
Using $watch on the value in the DataService? I have not tried this but I am hesitant to hinge an app this size on hundreds of $watches for performances reasons.
A third-party library like bacon.js (or any of a dozen others) that may simplify the event spaghetti, or create observable models that my controllers can watch without the risk of $digestageddon. Of course, if there is a concise way to handle my issue using Angular, I'd prefer not to muddy the app with 3rd party dependencies.
Something that lets controllers actually reference .service modules by reference, so I don't have to depend on tons of event wiring, complex state hierarchies, 3rd party libraries, or seeding the app with hundreds of $watches and then kicking off $digests to update controllers' references to Angular services?
Some solution that relies on time-tested OO and design patterns and not a 3rd-party library or framework that has a version that starts with 0.*.
Thanks in advance... I appreciate the help!
This is no problem of ui.router. If you intend for your model (your data service) to be a single source of truth, you have to refrain from destroying it.. err.. the reference to it that is. And in your case, assigning a primitve (a string) directly to the scope, instead of a reference to it. In other words...
var password = {pw:'initial value'};
and then later setting/binding only on
password.pw = newpassword
{{password.pw}}
Heres a fiddle. And also here is a short little read on scopes, It also includes a video of an angular meetup where Misko talks about "always have(ing) a dot in your model" link and how the $scope is a place to expose your model, not be your model. (aka not a place to assign primitives like password = 'initial value')
Hope this helps!
try remove the animation property of your ion nav view.
remove the property
animation="slide-left-right"
it would be ok.

Reusing DbContext object created in Spring.Net across controllers and actions

What is better? Or maybe - is the following a good practice?
I use Spring.net to create an instance of DbContext and then inject it into every controller for use in actions. The object is a singleton. Sometimes I get an exception which says that the "The ObjectContext instance has been disposed.." I suspect that this might be the reason, however this is not repeatable, and so far my application is only used by me during the development.
Now, would it be better to create a DbContext in every controller class and reuse in it's actions; or maybe create the DbContext object in every action itself; or just set it in the Spring config not to be a singleton, so it is created every time it is being accessed?
It is best to inject your dbcontext using request scope. That way, the context is created on the start of a request and disposed at the end. During the request you'll have a db context available so that it can handle lazy loaded objects for you.
When you register as a singleton, the dbcontext is shared for all requests, which most of the time isn't what you want. For instance, it might be that it hold a reference to all your loaded objects, potentially loading the entire db into memory.

Unity to return new instance of service

I have come across a bit of a problem while using Unity and WPF. The scenario is I have a WPF application which follows the MVVM design pattern. A have a module called ViewKDI. Within this module I have a service called ViewKDIService, the ViewKDIService service utilises another service called UserService.
Every time I load the module ViewKDI I want Unity to return me a new instance of both the ViewKDIService and the UserService.
I have put the below in the shell bootstrapper:
Container.RegisterType<IUserService, UserService>();
In the ViewKDI module I have put the following:
Container.RegisterType<IViewKDIService, ViewKDIService>();
Each time the ViewKDI module loads the ViewKDIService constructor is called. However the UserService constructor is only called the first time, this means that I am not getting a new instance of UserService.
I require unity to give me a new instance of UserService too so that I can manage this session separately from the rest of the application.
Any ideas?
Thanks
Faisal
Unity's default behaviour is to create a new instance of each object each time one is requested, so you shouldn't be seeing this behaviour.
From what I can gather from the source code and MSDN documentation (this is a good read), you can specify a "lifetime manager" object when you register a type to tell Unity how the type should be constructed and cached. Using the TransientLifetimeManager (which essentially does no caching) will cause Unity to re-create the class each time. So try this:
Container.RegisterType<IUserService, UserService>(new TransientLifetimeManager());
... and see if it creates a new UserService each time.

Resources