2

I don't have a problem, but I'm trying to prevent a problem from occurring in the future and would like a little help figuring out the proper way to approach this. I have a vendor who will be posting XML to a webpage that I have created. This would happen potentially every 2 minutes. The web page will then read the XML posted and insert into a Database. Serializing the XML and inserting is not good enough so I have to do a little bit of parsing before I send the data to the database. I created a static class that looks like the following.

using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// Summary description for Accounting /// </summary> public static class Accounting { public static String currentFile = ""; public static List<string> PurchaseOrder = new List<string>(); public static List<string> item = new List<string>(); public static List<string> unitPrice = new List<string>(); public static List<string> shippingCharge = new List<string>(); public static List<string> handlingCharge = new List<string>(); public static List<string> discountAmount = new List<string>(); public static List<string> UOM = new List<string>(); public static List<string> invoiceNumber = new List<string>(); public static List<string> supplierNumber = new List<string>(); //{ get; set; } public static List<string> supplierInvoiceNo = new List<string>(); public static List<string> account = new List<string>(); public static List<string> fund = new List<string>(); public static List<string> org = new List<string>(); public static List<string> prog = new List<string>(); public static List<string> activity = new List<string>(); public static List<string> location = new List<string>(); public static List<string> distributionType = new List<string>(); public static List<string> distributionValue = new List<string>(); public static List<int> sequence = new List<int>(); public static List<string> quantity = new List<string>(); public static List<string> dueDate = new List<string>(); } 

This class is static because I need to operate on the variables from different methods. Now here is where things get tricky, I keep reading that if I use static variable in a .NET web application I will end up sharing the variable across sessions. This could potentially be a nightmare for me. so I looked into the singleton pattern and I have also found this Static variables in web applications solution throught stackover flow. I read that I should do something like this

public class SingletonPerRequest { public static SingletonPerRequest Current { get { return (HttpContext.Current.Items["SingletonPerRequest"] ?? (HttpContext.Current.Items["SingletonPerRequest"] = new SingletonPerRequest())) as SingletonPerRequest; } } } 

My problem is that I don't know how can I convert my class to basically do what the above is doing. In other words how do I set class to follow this singleton request pattern. Forgive my stupidity if this does not make sense. My ultimate goal would be to have every request to the page have its own session of accounting variables and not get shared across session. Any help would be greatly appreciated.

1
  • If you don't want anything shared between requests, why not just avoid using static and use an actual instance? Create the instance, and pass it as a parameter to the methods that need to access the data. Commented Dec 7, 2014 at 17:31

2 Answers 2

1

Here is your class:

using System; using System.Collections.Generic; using System.Linq; using System.Web; public class Accounting { public static Accounting Current { get { return (HttpContext.Current.Items["Accounting"] ?? (HttpContext.Current.Items["Accounting"] = new Accounting())) as Accounting; } } public String currentFile = ""; public List<string> PurchaseOrder = new List<string>(); public List<string> item = new List<string>(); public List<string> unitPrice = new List<string>(); public List<string> shippingCharge = new List<string>(); public List<string> handlingCharge = new List<string>(); public List<string> discountAmount = new List<string>(); public List<string> UOM = new List<string>(); public List<string> invoiceNumber = new List<string>(); public List<string> supplierNumber = new List<string>(); //{ get; set; } public List<string> supplierInvoiceNo = new List<string>(); public List<string> account = new List<string>(); public List<string> fund = new List<string>(); public List<string> org = new List<string>(); public List<string> prog = new List<string>(); public List<string> activity = new List<string>(); public List<string> location = new List<string>(); public List<string> distributionType = new List<string>(); public List<string> distributionValue = new List<string>(); public List<int> sequence = new List<int>(); public List<string> quantity = new List<string>(); public List<string> dueDate = new List<string>(); } 

You can use the singleton like that: Accounting::Current.quantity

Note:

Using a static class is an antipattern in OOP. A static class is like a namespaced collection of method. You cannot instantiate objects that preventing you from using inheritance, interfaces, low coupling, dependency injection, ... Always use a singleton instead. This will help you to make a better architecture. You also should take a look at SOA (Service Oriented Architecture) in OOP and then in HTTP (REST webservices).

Sign up to request clarification or add additional context in comments.

7 Comments

Gnucki, so in essence every request would get a unique instance of accounting, right? that's what Im worry about. I'm worry that if one request comes in first and has not finished and then a second request comes in behind it and start operating on the accounting class it would potentially have awkward results.
Yes, there will be only one instance of Accounting for a same request. As the context is linked to one only request, this instance won't be shared between requests and so between users. Just open 2 pages of your website to test it!
This is a good implementation of a Singleton. I just wanted to note that it assumes there's only one web server. If you have multiple servers, you would need to employ additional tactics to ensure both servers use the same object.
No this object is a singleton on a request basis and not on a user basis.
I stand by my statement. Two IIS web servers won't share the same HttpContext object, so a value in one won't be seen by the other. This is why a lot of web farms use sticky sessions, so that the same server always responds to a particular user.
|
0

The Singleton pattern is used to ensure a single instance of an object is shared across an entire application, so it sounds like the opposite of what you are trying to achieve.

In the latter half of your question, it sounds like you want a separate instance for each request, which is essentially how ASP.NET handles objects by default (read up on Page.Load and Unload on the ASP.NET lifecycle overview page for details).

If that's the case, you should not need to do anything special except convert this from a static class to a normal class. What behavior are you seeing?

As an aside, you may want to look into Linq for Xml, which is built into the framework and could simplify your XML parsing. With Linq, you could potentially get rid of the need for many of those static variables by using XML queries to retrieve data.

5 Comments

Thanks Neontapir I'm just afraid that if two request come in simultaneously I would end up possibly overridden the list of string by the second request. I'm not seeing anything strange yet but I'm trying to prevent any problems from occurring in the future.
As the lifecycle documentation demonstrates, a new copy of the Page class is created upon each request.
yes but static classes are shared across user sessions. That's the problem that I can potentially encountered. Atleast that's what I'm reading from stackoverflow.com/questions/14154892/…
Correct, hadn't noticed that your class was static. With a static class, you get a new object once on first load. I edited my answer. For a new object per request, just remove the static keywords.
neontapir I wanted to take advantage of the static variable and also have them not be shared across request. It appears that the code above By Gnucki gets me that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.