Blazor Serverside singleton service, Changes in one browser are reflected in another, when loading the same page - blazor-server-side

In Blazor serverside, I created a shopping cart in a website using a singleton service, And I expected different users have different instances of this service, But when I load the website in two types of browsers, Adding an Item to cart is reflected in another browser, And even I can see the change, (I also used a singleton service for each user's data and the site is published to the web). Is this the correct behaviour for singleton services and how to solve it?

This is the expected behavior of a singleton service. In your case you should use the scoped service.
Transient lifetime services (AddTransient) are created each time they're requested from the service container. This lifetime works best for lightweight, stateless services.
Scoped lifetime services (AddScoped) are created once per client request (connection).
Singleton lifetime services (AddSingleton) are created the first time they're requested (or when Startup.ConfigureServices is run and an instance is specified with the service registration). Every subsequent request uses the same instance. If the app requires singleton behavior, allowing the service container to manage the service's lifetime is recommended. Don't implement the singleton design pattern and provide user code to manage the object's lifetime in the class.
Taken from the Microsoft Docs.
Also, note that lifetimes work differently in Blazor WebAssembly and Blazor Server. See Microsoft Docs.

Related

Background tasks with .NET CORE Lifetime and DI injection

I want to use background tasks in asp.net core.
I found helpful documentation https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio
I wonder why their lifetime apparently is scoped: Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
What is a scope in this context?
For web applications, a scoped lifetime indicates that services are created once per client request (connection). Register scoped services with AddScoped.
In apps that process requests, scoped services are disposed at the end of the request.
While I do understand what that means for e.g a standard http get request to an api,
I do not understand the meaning for a background worker.
Imho it would make more sense to have a singleton backgroundworker. I certainly do not want to have multiple instances running at a time in my application.
Another thing is DI in background workers which apparently differs fron standard services:
To use scoped services within a BackgroundService, create a scope. No scope is created for a hosted service by default.
I cannot confirm that:
services.AddHostedService(x => new DataPersister(x.GetRequiredService<IAsyncDocumentSession>(), x.GetRequiredService<ILogger>()));
seems to work just fine.
You have to read the sentence “Hosted service that activates a scoped service” within its full context:
This article provides three hosted service examples:
Background task that runs on a timer.
Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
Queued background tasks that run sequentially.
(from “Background tasks with hosted services”, emphasis mine)
So it is not the case that hosted services have a scoped lifetime. All hosted services added using AddHostedService() are actually added with a singleton lifetime, ensuring that there will only ever be a single instance of it.
What the article refers to is the situation when you need to consume a scoped service, like a database connection, within a hosted service. Since you cannot inject scoped dependencies into a singleton service, you will need a different solution there. And the solution usually involves having the singleton service (the hosted service in this case) create a service scope itself from which it can then retrieve the scoped dependency.
I went into more details about the service scopes in this recent answer to a similar question if you are interested.

Session variable equivalent in OWIN self-host

I have a sample web API hosted in an OWIN process (self hosted, not in IIS). I get a JWT token in my controller and I want to be able to retreive it in another part of the application, a class that implements NserviceBus IMutateOutgoingTransportMessages. In my other web application POC (hosted in IIS), I used a simple session variable and it works just fine. But I'd like to know what would be the best way to do it in my new OWIN self hosted environment ? Static property in static class ?
This question is really broad and difficult to answer without detailed knowledge of your specific needs. Here's my interpretation of your issue:
You're already signing each request, perhaps storing the token in the browser sessionStorage (or even localStorage), but this does not suffice
You need to retrieve the token outside of or not in relation to any request cycle (if not, this is probably where you should be looking for answers)
Your application does not need to be stateless
Just one static property for one token in a static class would of course start breaking as soon as more than one request hits the application at the same time. Implementing a class that maintains a list of tokens may be a solution, although I can't tell what key you should use to identify each token. Interface details would vary depending on things like if you need to retrieve the token more than once.
Thread safety issues would apply to all handling and implementation of such a class. Using Immutable Collections and functional programming practices as an inspiration may help.
If lingering tokens poses a problem (and they probably would from a security perspective, if nothing else), you need to figure out how to make sure that tokens do not outstay their welcome, even if the cycle is for some reason not completed.
Seeing how you used Session as a solution in your POC, I'm assuming you want some similar behavior, and that one user should not be allowed to carry two tokens at the same time. You could store the tokens i a database, or even in the local file system, making maintenance and validity a separate issue all together.
There are implementations of cache-like functionality already available for OWIN self-hosted applications, and maybe one of those would serve as a shortcut to implementing everything yourself.
If this token business in fact is the only reason for introducing state in your application, then the best solution IMHO would be to rethink your architecture so that the application can remain stateless.
I'm facing a similar dilemma on a server i'm currently developing for a customer. My problem is that the server must make calls (and retain a live connection) with a legacy, multithreaded DLL, (aka the SDK).
I struggled to get this working on IIS with a regular Web API project. Failed badly since IIS recycles threads when it determines that a thread is going rogue... witch is what the SDK thread looks like in that perspective. Also, the SDK must be able to callback on the caller (client - single page app) and for this I'm using SignalR.
I then tried a multi-part system (single page + web api on IIS + WCF service for the SDK integration). But it is a real nightmare to manage because of the 2 way async communication that must occur between all apps. Again: failure.
So I reverted to a single self hosted OWIN + WebAPI service in a console app (for now). My problem is that some of the calls are lengthy and are processed in a worker thread. I managed to pass the SignalR client id in each ajax calls via headers. I can extract the id when in web api controller. But when the task goes async, I need to get the id (via an Unity injected service) from the class that manages the async task. This is where my problem is similar to yours. In IIS hosted apps, we have HttpContext. It is contextualized on each client calls, and follows any thread changes in the pipeline... But not in self hosted OWIN WCF apps...
I'm looking into Thread Local Storage, CallContext... and other means of keeping track of the original caller info during the lifecycle of the async call. I have read about OWIN pipeline, I can capture the info in a OWIN middleware... but how to safely keep that info for use in injected services? I'm still searching for an answer...
I was wondering if you have found a solution to this rather interesting problem ?
I prefer adding to your thread rather than start another parallel thread / SO question.

Using session in wcf

If I set my servis instance as Per Session or Single can I send some data between services instance in session? It should be done in Asp.net session - HttpContext.Current.Session
or wcf have own session ?
As I said - WCF is not ASP.NET and its session handling is vastly different. While ASP.NET sessions and WCF sessions are called the same - they are vastly different in their purpose and usefulness.
Read the MSDN page Using Sessions in WCF for more details.
One sentence reads: There is no general data store associated with a WCF session. - so the answer is no - sessions in WCF are not meant for data storage.
WCF sessions are merely to "tie together" several messages into a conversation. By default, with the "per-call" model, each WCF service request would get its own, freshly instantiated service class instance to handle the request, and that service class instance will be freed after returning the answer. Using sessions avoids this - the service class instance handling the first call of a session will stay alive on the server side (and thus also taking up memory on the server) and will handle all subsequent requests within the same session.
WCF and web services in general should however preferably be stateless, so sessions are a bit of an oddball architecture in a proper SOA environment - and that's most likely why sessions in WCF are also not nearly as useful as ASP.NET sessions are for web apps.
To remain stateless and support the per-call method (the preferred best practice), if you need to store data between calls, store it in a persistent store (e.g. a database) and fetch it back from there when needed later on.
If you're hosting services in IIS, you can enable ASP.Net Compatability mode. This will allow you to use ASP.Net session state, just like you would in a web application.

WCF Service Design

We currently have a WCF Service which is beginning to reach it's limits performance wise.
We have decided to add another server which will host another instance of the WCF Service.
We have web applications which must communicate with a specific server based on context... e.g. If the web application is dealing with objects from ServiceInstance1 then requests must be directed to ServiceInstance1's EndPoint. If the web application is dealing with objects from ServiceInstance2 then requests must be directed to ServiceInstance2's EndPoint.
I initially thought that a "Intermediate Service" or "Service Manager" could be created, the web application's Service Reference would be updated from the individual Service Instance to the "Intermediate Service" or "Service Manager" and said service would act as a "Broker" to the various Service Instances.
How is this accomplished?
I have currently added a ServiceReference to each service from the Manager however it seems that once a Service is "Referenced" it's types becomes specific to the that of the ServiceReference e.g.
ServiceInstance1's type's are all {ServiceInstance1}.
ServiceInstance2's type's are all {ServiceInstance2}.
I need the types to be the same on the web application end, so this obviously seems like the wrong way to do it.
I would also like that when methods are called on the client generated from referencing the "Intermediate Service" or "Service Manager" that the correct Service Instance is invoked, e.g.
IServiceManager.GetProjectById( {GUID} ) ->
Comes Back to ServiceManager ->
Determines which host has the project and returns the ProjectObject from the correct ServiceInstance.
Where ProjectObject is a Type Defined in ServiceInstance1 and ServiceInstance2.
I think the original service needs to have some of the DLL's pulled out so they can be referenced from the web application side and ServiceManager and a GenericWCF Client can be made.
If I am right hooray for me If someone can point me in the right direction I would appreciate it. If I am wrong can someone please scold me and show me how this is properly done!
The way to solve your problem is to create shared assembly with types used by both services. Reference this assembly on the client consuming your services (manager) and when creating proxies by Add service reference mark Reuse types from referenced assemblies.
What you are building is very simple message router. In WCF 4.0 there is additional support for routing services so you should check those features before developing your own. For WCF 3.5 MSDN magazine contains articles about building message router - part 1, part 2.
Just to Answer this and close it I wound up utilizing the Routing Strategy in .Net 4.0 and custom client class which I modeled after the generated classes from the Proxy.
Before I had the custom client ready I used the auto generated client code and I derived a class from it which allow me to change which service it was connecting to. I determined which service via a property which was made available on all service objects which were serialized.
Long story short this is working 100% as expected including the ServiceManager which can even be bypassed on certain calls which we allow.
We even have the ability to move a project from server to server during run time!
Thanks to everyone who helped! (Especially myself for actually doing the work without being spoon fed)
The easiest way to accomplish what you're trying to do is to stop generating your proxies using the server-hosted URL of the service. Instead, generate your proxies from the *.xsd and *.wsdl locally, and merely change the URL of the endpoint. Alternatively, you can use ChannelFactory<T> to generate proxies on-the-fly, and reference your interface .dll on the client side.
Once you've done that, you can use any common webserver load balancing technique to balance the load between the servers.
Not to put too fine a point on it, but Visual Studio's "Service Reference" is not useful, and should not be used, for services you develop. It's useful only for services developed externally, whose URL and contracts are likely to NEVER change. I personally have never had occasion to use it. For your own services, you should probably be using ChannelFactory<T> or a class based on ClientBase<T> to work out the proxies.

WCF - StructureMap - Caching objects for the duration of the request only

So I already have a working implementation of StructureMap with the WCF service (including custom instance provider, behaviors, etc.)
When I try to have an object that is instantiated only once per user request, I use the InstanceScope.HttpContext and it throws because the context is null.
Do anyone have a proper way of doing that?
On the server-side of the WCF service? By default, WCF has nothing to do with ASP.NET and thus all your HttpContext etc. aren't there.
By default, your WCF services will be called on a "per-call" basis, e.g. each request gets a brand-new, separate, totally isolated instance of your service class. Why not just put those things into the service class as internal fields??
Or you might want to check out this blog post on how to abstract request state and providing sample implementations for ASP.NET (using HttpContext.Items) and WCF.