Is the singleton in ASP.NET per session or per machine? - asp.net

I have an web application written in ASP.NET (FW 3.5) (along with some VBScript, this is a legacy app) that uses a utility class in the backend that logs error.
I need to log several values that a user has entered in the front-end.
Since the utility class has no access to the front end (or any HTTP services),
i created a singleton class within the utility namespace that my front end UI can access and store information about the user.
I guess more specifically, I am wondering if there's a way to store session variables that can be shared across the web application and web services through a class referenced by both of the application and web services. For example, I have an error handling class that is used by both instances that required information about the user. Is there a way to create a per-session singleton to hold that information, so that my error class will have access to the user info? or is this not possible - that i'll need to pass the information around as they are needed?

If your singleton implementation uses a Shared variable, your instance will be unique within a single AppDomain.
That said, I would try to avoid using a Singleton simply to facilitate passing data to your utility class.

Related

addScoped service lifetime in an ASP.NET Core multithreaded application

I know that AddSingleton() creates a single instance of the service when it is first requested and reuses that same instance in all the places where that service is needed.
If my ASP.NET Core application is multi-threaded, does that mean all HTTP requests from all users will share the same object instance created by dependency injection (DI)?
If so, that would be not a good way if the application process data to be stored. Are there any best practices?
As mentioned in Microsoft documentation, Service lifetimes, it depends on your specific case.
Presumably, if you have a service, A, and you want to create a new instance on every single request, you can use AddScoped() rather than AddSingleton(). A scoped lifetime service would be created per client request.
If for example, it was some shared data that possibly doesn't change between requests such as some values that are computed at application startup and reused throughout the lifetime of the application, then that is a usable scenario.

Web Api And Static Classes

With regard to Web Api, are static classes loaded into memory at every request? If not, what should be used to use the same static class for every request and load it into memory once? I am thinking of loading a class containing a dictionary.
A static class is loaded once and static members are shared between all instances - if you wish to share a dictionary, then declare it as a static member of a class (the class itself does not need to be static).
One thing that is important to note: if your app is running under IIS and you configure it to allow multiple process instances, then those instances will NOT share static class instances since they are in different processes. This is not the default - if you use default IIS settings, then only one process will service requests and you will be fine - otherwise you will need to have a different approach, for example a secondary shared in-memory cache or service or database that then becomes the shared storage for the dictionary.
A static type is initialized only once per application domain and only when referenced. Web API 4.x and previous (not core version) are hosted in IIS which hosts the site in their own application domain 1 domain per site.
If you want a shared readonly dictionary then you could make use of a static type, it will be loaded once and all your loaded instances could reference that same dictionary regardless of what request they were on. I am not advocating this idea as that would be going into the realm of opinion, I am simply stating that this is possible.

Application level variables in web api c#

I am in a situation where requirement is to keep an application level object in web api which can be accessed by all requests. I know one can use HttpContext.Current but that is not required since HttpContext is only for the liftime of request. I need a solution where i can keep an object that all requests can access and update as required.
Use a static class to hold your application level objects. static classes and static data members are created once for the application lifetime and all ASP.NET requests can access them.
I learnt it the hard way. Some time back, I mistakenly created a static field to hold customer-specific database connection string, in a ASP.NET Web API project and it became a mess. On each customer's login it was being set (overridden) in the code and the requests from the previously logged customers were using this newly set static SQL connection string for their queries. It was an embarrassing situation when customer's inadvertently saw each other's data.
You could use SessionState (per session).
I.e.
Session["YourDataKey"] = ApplicationLevelObject;
And then check the session state variable on each request that requires it.
However if you require the object for longer, I.e. every single user session, then I would suggest persisting your object to a database. You could use an ORM such as Entity Framework.
Cheers

referencing a class as a web service

Whats the best way to implement this.
I am building application that will be hosted as a web service. This app takes an employeeID and returns an employee object that contains lots of info regarding the employee. (name, status, full-time/part-time, etc)
I want the two existing apps we have (and more to come) to be able to call a method that the web service will have and return the employee object. (also at time this web service that returns the object may have new fields added to it - Pay rate, etc)
How would I go about creating a new object from this web service reference in the existing applications.
Would I decalre it like Dim Employee as new emp_webservice.employee ?
And then be able to use this object within the app? Or would the better practice be to also included the same class files? It seems like this would not be the way to go, since if I make a change to that class I then have to make it in all places
Thanks for any clarification on this.
When you add a reference to a web service in a .net application, the objects exposed by that web service exist in the namespace that you created for that web service when it was added to your application.
So, any reference to classes from that web service would need to reference the namespace for that web service, as you have indicated. You could also have an Imports WebServiceNameSpace if you don't want to fully qualify every class.
You can't really include the class files if you are using the automatic web service interface generation functionality that VS.Net provides.
Also, if you change properties in the web service, those updated properties won't be propagated to the client until you update the web service reference in your project.
Finally, if you want to add methods or additional properties to the web service classes on the client side, you can use Partial classes.
For example, let's say that the web service only provides an hourly pay rate, but I want to show a weekly salary in the client. I can extend the web service class as follows:
Namespace emp_webservice
Partial Public Class employee
Public Function GetWeeklyPayRate() As Decimal
Return Me.HourlyRate * 8 * 5
End Function
End Class
End Namespace

Avoiding having to map WCF's generated complex types

I have an ASP.NET MVC web app whose controllers use WCF to call into the domain model on a different server. The domain code needs to talk to a database and access to the database server isn't always possible from web servers (depends on the customer site) hence the use of WCF to get to a place where my code is allowed to connect to the database server.
This is configurable so if the controllers are able to access the database server directly then I use local instances of the domain objects rather than use WCF.
Lets say I have a page asking for person details like age, name etc. This is a complex type that is a parameter on my WCF operation like this :
[OperationContract]
string SayHello( Person oPerson);
When I generate the client code (eg; by adding a service reference in my client) I get a separate Person class that fulfills the wcf contract. The client, an MVC web app, can use this client Person class as the view model and all is well. I pass that straight into the WCF client methods and it all works brilliantly.
If my mvc client app is configured to NOT use WCF I have a problem. If I am calling my domain objects directly from the controller (assume I have a domain access factory/provider setup) then I need the original Person class and not the wcf generated Person class. This results in my problem which is that I will have to perform mapping from one object to another if I don't use WCF
The main problem with this is that there are many domain objects that will need to be mapped and errors may be introduced such as new properties forgotten about in future changes
I'm learning and experimenting with WCF and MVC can you help me know what my options are in this scenario? I'm sure there will be an easy way out of this given the extensibility of WCF and MVC
Thanks
It appears that you are not actually trying to use a service-oriented architecture. In this case, you can place the domain objects into a single assembly, and share it between the WCF service and the clients. When creating the clients, use "Add Service Reference", and on the "Advanced" tab, choose "Share Types". Either choose to share all types, or choose the list of assemblies whose types you want to share.
Sound service-oriented-architecture dictates that you use message based communication regardless of whether your service is on another machine, in another process, in another appdomain, or in your appdomain. You can use different endpoints with different bindings to take advantage of the speed of the link (http, tcp, named pipes) based on the location of your service, but the code using that service would remain the same.
This may not be the easiest or least time-consuming answer, but one thing you can do is avoid using the "add service reference" option, and then copy your contract interfaces to your MVC application and initiate the connection to WCF manually without automatically creating a service proxy. This will allow you to use one set of classes for your model objects and you can control explicitly when to use WCF or not.
There's a good series of webcasts on WCF by Michele Leroux Bustamante, and I think in episode 2, she explains how to do exactly this. Check it out here: http://www.dasblonde.net/WCFWebcastSeries.aspx
Hope this helps!
One sound option is that you always use WCF, even if client and server are in the same process, as Aviad points out.
Another option is to define the service contracts on interfaces, and to put these, together with the data contracts into an assembly that is shared between client and server. In the client, don't use svcutil or a service reference; instead, use ClientFactory<T>.
This way, your client code will use the same interfaces and classes as the server.

Resources