Where is state stored in fluxor? - c#

I am new to working with state management. Currently I am working on a blazor application and I stumbled across the "fluxor" framework which allows state management via the flux pattern.
Fluxor is working perfectly for me, however I can't seem to figure out where the State of a page is actually stored.
Is it in cache, a db or some other fancy way? Is there a way for me to see that stored data in the browser?
I use fluxor on the client side of my application by the way.
Thanks for helping me out!

State is kept in memory. You can view the state with a nice GUI by enabling Redux Devtools with .UseReduxDevTools() like this:
services.AddFluxor(o => o
.ScanAssemblies(typeof(SomeType).Assembly)
.UseReduxDevTools());
Then use the redux devtools addin:
https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en
If you wish to save the state to localstorage or a database I made a library to persist the state called Fluxor.Persist:
https://github.com/Tailslide/fluxor-persist

An IStore is instantiated as a Scoped dependency. Ultimately this is the root of everything for the current user.
When you inject IStore, IState<Whatever> IDispatcher, IActionSubscriber they will ultimately come from the state that is stored within that IStore instance.
If you inject IStore into something you can iterate through its Features property, which is a dictionary of IFeature keyed by name (the name being from IFeature.GetName).
The IFeature has an object GetState() method you can use to grab the state.
This is the non-generic way of accessing the state. The state is actually stored using generics.
Look at the ReduxDevTools code and you will see an example of how to get all state (to send to ReduxDevTools browser plugin) using IStore.Features and GetState
https://github.com/mrpmorris/Fluxor/blob/master/Source/Fluxor.Blazor.Web.ReduxDevTools/ReduxDevToolsMiddleware.cs#L67
and in the OnJumpToState method it shows how I restore historical states from the browser plugin
https://github.com/mrpmorris/Fluxor/blob/master/Source/Fluxor.Blazor.Web.ReduxDevTools/ReduxDevToolsMiddleware.cs#L92

Related

Injecting a singleton into scopedService

I'm working on adding push notification into my ASP.NET core 2.0.0 webApp. I want to have a notification service that would have a badgeCount member which I would update when I send out notifications or when I mark something as read.
I wanted to make this a singleton, but it seems like I can't use dependency injection for singletons. I need access to my dbContext and maybe some other Identity /or Entity services later.
Would it make sense for me to make my notifcation service a scopedService instead of a singleton so that I can use DI? Then have a notificationBadge singleton that I would inject into my scopedService so I can maintain it?
I'm doing this so that I don't have to calculate the badge count each time (involves using queries)
EDIT: Actually, after writing this I realized that singletons are probably only instantiated once on server startup and not per user. So my initial approach wouldn't work even if I could use DI. I'd probably have to add a field on my user class that extends the IdentityUser then right? Or is there a way around this so that I don't have to update/save this to any db record?
Understanding DI
So to try and cover your question DI is certainly what you want in terms of most things inside your application and website. It can do singletons, as well as scoped and transcients (new copy every time).
In order to really understand DI and specifically the .Net Core implenentation I actually make use of the DI from .Net Core in a stand-alone .Net Standard open source library so you can see how it is done.
Video explaining the DI and showing me make and use the DI outside of ASP.Net Core scene: https://www.youtube.com/watch?v=PrCoBaQH_aI
Source code: https://github.com/angelsix/dna-framework
This should answer your question regarding how to access the DbContext if you do not understand it already from the video above: https://www.youtube.com/watch?v=JrmtZeJyLgg
Scoped/Transcient vs Singleton
What you have to remember when it comes to whether or not to use a singleton instance is singletons are always in-memory, so you should always consider and try to make things scoped or transcient to save memory, if the creation of that service is not intense or slow. So it is basically a trade off between RAM usage vs speed on some generate grounds.
If you then have specific types of service the decision becomes a different one. For example for DbContext objects you can think of them like a "live, in-memory database query/proxy" and so just like SQL queries you want to create them, execute them and be done with them. That is why they are made scoped, so that when a controller is created (per request) a new DbContext is created, injected, used by an action and then destroyed.
I guess the simple answer is it doesn't usually matter too much and most applications won't have any major concern or issues but you do have to remember singletons stay in-memory for the lifecycle of your application or the app domain if you are in a rare multi-domain setup.
Notification Count
So the main question is really about badges. There are many things involved in this process and setup, and so I will limit my answer to the presumption that you are talking about a client logged into a website and you are providing the website UI, and want to show the badge count for, and that you are not on about for example some Android/iOS app or desktop application.
In terms of generating the badge count it would be a combination of all unread messages or items in your database for the user. I would do this calculation on request from the user visiting a page (So in an Action and returned to the view via Razer or ViewBag for example) that needs that information, or from requesting it via Ajax if you are using a more responsive/Ajax style site.
That again I presume is not an issue and I state it just for completeness and presumptions.
So the issue you are asking about is basically that every time the page changes or the badge count is re-requested you are concerned about the time in getting that information from the database, correct?
Personally I would not bother trying to "cache" this outside of the database, as it is a fast changing thing and you will likely have more hit trying to keep the cache in-sync than just calling the database.
Instead if you are concerned the query will be intensive to work out the badge count, I would instead every time any addition to the database of an unread/new item, or a marking of an item as read is done, you do a "SetUnreadCount" call that calculates and writes that value as a single integer to the database so your call to get the unread count is a Scalar call to the database and SUPER quick.

ASP.Net Razor C# Variables Accessible to All Pages

For starters, please forgive me and please correct me on my terminology. I am quite sure of the correct words to use for what I am trying to accomplish.
I have been given the task of building an ASP.Net Razor web site. It is something new to me. I am very proficient in PHP and ASP Classic. What I need to be able to figure out is how to declare a variable that is accessible everywhere. I do not know if in the .net world you call it a global variable or application variable or something else. But, here is how I would do this in Classic ASP.
In Classic ASP, I would have a file named VarFunct.asp. It would be the file that I declare my variables and have various functions I would access from anywhere. I would include the VarFunct.asp file on all of my pages. Anyway this is what I am really trying to do (written in how I would do it in Classic ASP)…
SelLoc = Request("SelLoc")
If Len(Trim(SelLoc)) = 0 Then
SelLoc = "All"
End If
In this case, Request("SelLoc") could be Request.QueryString or Request.Form. Then anywhere in my website I could use the variable SelLoc. So, in short... I need to be able to set a variable. Check to see if it is set by Request.Form, if not, check Request.QueryString, if not set the value to “All”. How do I write this? And where do I put it?
When I created the website using Visual Studio 2012, I selected ASP.NET Web Site (Razor V2).
This seems like it should be such a basic fundamental task of any website that has any kind of server side programming, but trying to find information and documentation online is near impossible, but probably because I am not using the correct terms for my question. I have not found any Razor tutorials that talk about setting variables that can be used globally across the website.
If someone could please help me out here by either telling me what I need to do or point me to a good tutorial, that would be great.
what you are looking for is called Static Class/Member
This will allow you to store and share data for the whole application.
BUT! since web server is multi-threaded, you wouldn't want to do this or else you might run into the case where the data is overwritten by another request before you finished the current one.
If you need to pass data from controller to your View you can use ViewBag dynamic object
If you need to use the data anywhere else (for example in a helper class) then do
HttpContext.Current.Application["VariableName"] = something
It is basically a dictionary and each request will have a different Application object
There are several ways of doing this.
For your example I would assume that this particular variable can be different for different users that are using the application at the same time. This is more of a Session scope than Application scope.
In this case you could simply use inheritance and make a base controller and/or base view model class that all your other controllers and/or view models inherit from. This way you can pass it back and forth between the view and controller and read/update it whenever you need to.
You could also use the Request and HttpContext and Session objects that are built into asp.net, if they fit your need. A brief overview of some of their functionality can be found here: https://learn.microsoft.com/en-us/aspnet/web-pages/overview/api-reference/asp-net-web-pages-api-reference --- google searching specific ones yields tons of results.
If you truly want Application scope, you can of course use a static class for you utilize static methods. Then you don't need to include the class in every other class, but you would need to fully name qualify the method when you call it.
I would not recommend static variables at this level though. I can't imagine very many things that would need to change for every single user that you would change while the application instance is running. Most of these sorts of items that we use are caches (generally db lookups and such, that we don't want to retrieve from the db each time, and RARELY get updated). If you utilize caches, be very aware of your thread safety when updating them. Here is an msdn on caching: https://msdn.microsoft.com/en-us/library/aa478965.aspx --- Or application configuration settings, like the application environment. We pull most of those from a config file, and they are read only, we don't change them within a running instance of the application.

Best way to store data (single object) in Web API project without database

My project group and I are to develop a generic workflow system, and have decided to implement a single Node (a task in the workflow) as a C# Visual Studio Web API project (Using the ASP.NET MVC structure).
In the process of implementing a Node's logic, we've come across the trouble of how to store data in our Node. Our Node specifically consists of a few lists of Uri's leading to other Nodes as well as some status/state boolean values. These values are currently stored in a regular class but with all the values as internal static fields.
We're wondering if there's a better way to do this? Particularly, as we'd like to later apply a locking-mechanism, it'd be prefereable to have an object that we can interact with, however we are unsure of how we can access this "common" object in various Controllers - or rather in a single controller, which takes on the HTTP requests that we receive for ou Node.
Is there a way to make the Controller class use a modified constructor which takes this object? And if so, the next step: Where can we provide that the Controller will receive the object in this constructor? There appears to be no code which instantiates Web API controllers.
Accessing static fiels in some class seems to do the trick, data-wise, but it forces us to implement our own locking-mechanism using a boolean value or similar, instead of simply being able to lock the object when it is altered.
If I am not making any sense, do tell. Any answers that might help are welcome! Thanks!
Based on your comments, I would say the persistence mechanism you are after is probably one of the server-side caching options (System.Runtime.Caching or System.Web.Caching).
System.Runtime.Caching is the newer of the 2 technologies and provides the an abstract ObjectCache type that could potentially be extended to be file-based. Alternatively, there is a built-in MemoryCache type.
Unlike a static method, caches will persist state for all users based on a timeout (either fixed or rolling), and can potentially have cache dependencies that will cause the cache to be immediately invalidated. The general idea is to reload the data from a store (file or database) after the cache expires. The cache protects the store from being hit by every request - the store is only hit after the timeout is reached or the cache is otherwise invalidated.
In addition, you can specify that items are "Not Removable", which will make them survive when an application pool is restarted.
More info: http://bartwullems.blogspot.com/2011/02/caching-in-net-4.html

Design Issue (Unity, Reflection)

I am currently developing a Microsoft Word Add-In that communicates with a backend via webservices. The dialogs in this Add-In are created with WPF and I make use of the MVVM pattern. The viewmodels communicate with the repository over services. In order to decouple viewmodel and services I use the DI-container framework Unity.
There is some kind of state (I call it "Context", similar to the http-context) that depends on the active document at the time a window/viewModel was created. This context contains stuff like the active user.
Since a picture is worth more than a thousand words, I prepared a diagram to illustrate the design.
Now my problem is, that when a service method is called, the service needs to know what the active context is in order to process the request.
At the moment I am avoiding this problem by having one service for each document. But since this cuts across the statelessness of services, I don't consider it as a durable solution.
I also considered passing the context to the viewModel, so that I can pass it back to the service when calling a method there. But I see three problems here:
Technical Problems:
Each time I want to resolve a Window with Unity I would have to pass a ParameterOverride-object with the context - what creates dependencies to the concrete viewModel implementation.
=> Or is there a better way to achieve this with unity?
Cosmetical Problems:
I would have to pass the Context as object since the class for it is part of the startup-project and the ViewModels are not. When I now want to obtain data from the context, I'd have to cast it.
Consider a windowViewModel that contains data for a TreeView with hundreds of TreeViewItems. I would have to pass the Context to each of these "TreeItemViewModels" if I'd want to call a service-method in one of these.
So I'm wondering if there is a way of automatically "injecting" (maybe reflection?) the context into the viewModel at runtime without the viewModel knowing anything about it. This is probably impossible to achieve with Unity, but I'm always open to being convinced.
On the other side, when a method on a service is called, the injected context is automatically extracted (maybe by some kind of layer in front the actual service) and saved into some globally accessible property.
I hope that some of you can help me. I appreciate any kind of idea.

Managing global settings in an ASP.NET MVC application?

I am developing an ASP.NET MVC 5 application and I need to manage some global parameters, which are basically just a set of key-value-pairs. My requirements are the following:
Initial values are read from a server config file.
Parameters are available in every controller for both reading/writing and adding/deleting (like a new parameter can be added if certain controller is executed).
Parameters should surface subsequent request (either residing in Session or serialized in QueryString).
I should be possible to see and easily manage them (CRUD) using a special admin webpage.
My "brute force" approach for this would be just to implement a static class with List<Tuple<string,string>> to keep the settings, use System.Web.Configuration.WebConfigurationManager to populate initial values, use static properties to store and retrieve the list in a session variable and design a separate controller and view for managing the settings.
But this looks like re-inventing the wheel to me. Is there any (not necessarily full-fledged) pre-existing solution (in ASP.NET, or as a NuGet package) I might rest my efforts upon? Or maybe I am missing something fundamental in ASP.NET?
UPDATE: Depending on the nature of the parameter, some of them might have the lifetime of the Application, whereas some of them are bound to the current user session. Therefore they need to be either preserved in a Session object or "passed through" in every request.
That sounds like the most common approach, I don't see anything wrong with using session variables.

Categories