I've created a very simple helper class that I can use in my ASP.Net pages. The idea is that it is supposed to be a very simple way to log an on-page error or success (not a form validation error) and then display it to the user.
In my public helper class I have a class which has certain properties, as shown below:
public class UserMessage
{
public UserMessage()
{
Messages = new Dictionary<string, string>();
}
public string SummaryMessage;
public Dictionary<string, string> Messages;
public bool ShowMessages;
public bool ShowAsError;
}
I then have a variable which is used to store an instance of the UserMessage class, like so:
private static UserMessage _userMessage { get; set; }
I then have two public static methods, one to log a message, the other to display all the messages, like so:
public static void LogSummary(string summaryMessage, bool showIndividualMessages, bool showAsError)
{
_userMessage = new UserMessage();
_userMessage.SummaryMessage = summaryMessage;
_userMessage.ShowMessages = showIndividualMessages;
_userMessage.ShowAsError = showAsError;
}
public static string DisplayUserMessages()
{
if (_userMessage == null)
return string.Empty;
StringBuilder messageString = new StringBuilder();
messageString.AppendFormat("\n");
messageString.AppendLine(string.Format("<div class=\"messageSummary {0}\">", (_userMessage.ShowAsError) ? "invalid" : "valid"));
messageString.AppendLine(string.Format("<h3>{0}</h3>", _userMessage.SummaryMessage));
messageString.AppendLine("</div>");
return messageString.ToString();
}
The problem I have is that the _userMessage variable has to be a static variable, otherwise I get the error message "An object reference is required for the non-static field.......". The problem with the variable being static is that is stays in memory, so if the user receives an error message and then visits another page - the error message is still displayed!
I'm sure this is because I missed OOP 101, but how should I correct this?
Do not use static variable to keep messages per user! ASP.NET application is multi-threaded and using static variable is not thread safe. Store them in Session.
public static void LogSummary(string summaryMessage, ...)
{
HttpContext.Current.Session["userMessages"] = new UserMessage();
...
}
public static string DisplayUserMessages()
{
// get the value from session
var userMessage = (UserMessage)HttpContext.Current.Session["userMessages"];
// do the work
// do the clean up
HttpContext.Current.Session["userMessages"] = null;
// the messages will not be displayed on next request
}
Each request is handled by different thread, so the users will overwrite the _userMessage field and you cannot guarantee that messages for the current user will be displayed.
Pass the reference as an argument to the static member, or have it return a new instance like below:
public static UserMessage LogSummary(string summaryMessage, bool showIndividualMessages, bool showAsError)
{
var userMessage = new UserMessage();
userMessage.SummaryMessage = summaryMessage;
userMessage.ShowMessages = showIndividualMessages;
userMessage.ShowAsError = showAsError;
return userMessage;
}
In my opinion you try to face a problem with a wrong approach. Considering that you're developing service side component (ASP.NET) and you have to have perfect isolation between every user visits your site, I personally don't see any reason why do not use a backend database for error message holding where every record can be associated to a single user unique ID.
The simple ACID supported database (in practice almost any on the market) is a perfect fit in this case.
In this way you can pull from the database the message you need at the moment you need, and don't need more worry about any type of memory issue (at least from the perspective of this question)
Hope this helps.
Static variable will be shared within AppDomain - i.e. concurrent requests will share the same instance and hence your approach is problematic.
You should consider putting your user-message instance into the current HttpContext to get per request semantics as needed by your use case. For example,
public class UserMessage
{
public static UserMessage Current
{
get { return HttpContext.Current.Items["_User_Message"] as UserMessage; }
}
public static void LogSummary(string summaryMessage, bool showIndividualMessages, bool showAsError)
{
var userMessage = new UserMessage();
userMessage.SummaryMessage = summaryMessage;
...
HttpContext.Current.Items["_User_Message"] = userMessage;
}
public static string DisplayUserMessages()
{
var userMessage = UserMessage.Current;
if (userMessage == null ) return string.Empty;
...
}
// rest of the code
...
}
I would probably also make UserMessage constructor private.
Related
In my project I'm using some static variables which I use for storing values during the running lifetime of the application. Now, 99% of the time I'm only reading these values but from time to time I also need to update them and this will happen from different threads.
When thinking about what might happen with two different threads trying to access the same property e.g. concurrent read/write, I started to conclude that some form of synchronization would needed in order to avoid unexpected values being returned between different process or some risk of race conditions.
In essence I needed to derive a single source of truth. I realize that some properties are atomic like booleans, but my methodology mostly applies for the purpose of strings.
One of the challenges is that these static variables are referenced in many places and between different classes, so I also had to figure out an efficient way to solve this challenge without lots of code re-write.
I've decided to use concurrent dictionaries:
public static readonly ConcurrentDictionary<string, string> AppRunTimeStringDictionary = new();
public static readonly ConcurrentDictionary<string, int> AppRunTimeIntegerDictionary = new();
public static readonly ConcurrentDictionary<string, bool> AppRunTimeBooleanDictionary = new();
In my program.cs file, during the earliest stages of startup I simply add all of the properties needed for the running app:
DeviceProvisioning.AppRunTimeBooleanDictionary.TryAdd("UseGpsReceiver", false);
DeviceProvisioning.AppRunTimeStringDictionary.TryAdd("Latitude", String.Empty);
DeviceProvisioning.AppRunTimeStringDictionary.TryAdd("Longitude", String.Empty);
Then in one of my classes I hard code these properties:
public static bool? UseGpsReceiver
{
get
{
if (AppRunTimeBooleanDictionary.TryGetValue("UseGpsReceiver", out var returnedValue))
return returnedValue;
return null;
}
}
public static string? Latitude
{
get
{
if (AppRunTimeStringDictionary.TryGetValue("Latitude", out var returnedValue))
return returnedValue;
return null;
}
}
public static string? Longitude
{
get
{
if (AppRunTimeStringDictionary.TryGetValue("Longitude", out var returnedValue))
return returnedValue;
return null;
}
}
Now for updating these properties, which happens rarely but will be done every now and then, I'm updating these in just one location i.e. using a single method. This way I can use this common method and simply add more prperties to the switch case over time.
public static void SetRunTimeSettings(string property, object value)
{
switch (property)
{
case "UseGpsReceiver":
// code block
if (AppRunTimeBooleanDictionary.TryGetValue("UseGpsReceiver", out var useGpsReceiver))
{ AppRunTimeBooleanDictionary.TryUpdate("UseGpsReceiver", (bool)value, useGpsReceiver); }
break;
case "Latitude":
// code block
if (AppRunTimeStringDictionary.TryGetValue("Latitude", out var latitude))
{ AppRunTimeStringDictionary.TryUpdate("Latitude", (string)value, latitude); }
break;
case "Longitude":
// code block
if (AppRunTimeStringDictionary.TryGetValue("Latitude", out var longitude))
{ AppRunTimeStringDictionary.TryUpdate("Latitude", (string)value, longitude); }
break;
}
}
If I want to update a property then I simply invoke the method as such:
MyClassName.SetRunTimeSettings("UseGpsReceiver", true);
MyClassName.SetRunTimeSettings("Latitude", "51.1234");
MyClassName.SetRunTimeSettings("Longitude", "51.5678");
Because the properties themselves are public static then I can use the getter from anywhere in the app.
From my initial testing, everything seems to work.
Perceived advantages in this approach:
Using a separate dictionary for each type of property collection i.e. strings/integers etc, means I can simply add more properties to the dictionary any time in the future without the need for referencing a model class in the dictionary, as opposed to the dictionary below:
public static readonly ConcurrentDictionary<string, myModelClass> AppRunTimeStringDictionary = new();
Use of the concurrent dictionary (my understanding) is that any process trying to read the property value from the dictionary will always get the latest value, if a property is being updated then I have less risk in reading an old value. Not such an issue for structured logging but if I was storing keys/secrets/connection strings or anything else, reading an old value might stop some process from being able to function correctly.
Using the concurrent dictionary means I don't have to hand craft my own locking mechanisms, which many people seem not to like doing.
Dictionary applies its own internal locks on the individual objects, so any property not being updated can still be read by other processes without much delay.
If the public static getter ever returned a null value, my thoughts are it would be better to return a null value rather than returning the wrong value. I could always implement some kind of polly or retry mechanism somewhere from the calling process, some short delay before trying to retrieve the property value again (by which time it should have been updated from the other thread that was currently updating it)
Appreciate there will be other ways to approach this, so really what I'm asking here is whether anyone sees any issue in my approach?
I'm not planning to add that many properties to each dictionary, I just want a way to ensure that reads and writes are happening with some form of synchronization and order.
Your SetRunTimeSettings is awful. It relies on methods that follow the Try* pattern, but it itself does not. Also doing a TryGetValue just to then be able to call TryUpdate is just throwing away all of the value of Try* operators anyway. It's a hack.
And you have a clear bug in the code for the "Longitude" case - you're updating "Latitude" inside.
I'd suggest going old school and just do this:
private static bool? _UseGpsReceiver;
private readonly static object _UseGpsReceiverLock = new();
public static bool? UseGpsReceiver
{
get { lock (_UseGpsReceiverLock) return _UseGpsReceiver; }
set { lock (_UseGpsReceiverLock) _UseGpsReceiver = value; }
}
private static string? _Latitude;
private readonly static object _LatitudeLock = new();
public static string? Latitude
{
get { lock (_LatitudeLock) return _Latitude; }
set { lock (_LatitudeLock) _Latitude = value; }
}
private static string? _Longitude;
private readonly static object _LongitudeLock = new();
public static string? Longitude
{
get { lock (_LongitudeLock) return _Longitude; }
set { lock (_LongitudeLock) _Longitude = value; }
}
If you don't want to repeat all of the locks then maybe a Locked<T> class might be of use:
public struct Locked<T>
{
public Locked(T value)
{
_value = value;
}
private T _value;
private readonly object _gate = new();
public T Value
{
get { lock (_gate) return _value; }
set { lock (_gate) _value = value; }
}
}
Then you can write this:
private static Locked<bool?> _UseGpsReceiver;
public static bool? UseGpsReceiver
{
get { return _UseGpsReceiver.Value; }
set { _UseGpsReceiver.Value = value; }
}
private static Locked<string?> _Latitude;
public static string? Latitude
{
get { return _Latitude.Value; }
set { _Latitude.Value = value; }
}
private static Locked<string?> _Longitude;
public static string? Longitude
{
get { return _Longitude.Value; }
set { _Longitude.Value = value; }
}
If you are only setting a single string / int / bool at a time, then you don't need to any thread safety. If you are assigning any single value smaller than a machine word, any reading thread will either see the before value or the after value.
However it looks like you intend to set three values at the same time;
MyClassName.SetRunTimeSettings("UseGpsReceiver", true);
MyClassName.SetRunTimeSettings("Latitude", "51.1234");
MyClassName.SetRunTimeSettings("Longitude", "51.5678");
And I assume you want any reader to see either the old values or the new values. In this case you would need some thread synchronisation around every read / write. Which your current code doesn't have.
You could instead store the three values in a class, then update the reference to that instance in one write operation.
public class GpsSettings{
public bool UseGpsReceiver { get; init; }
public double Latitude { get; init; }
public double Longitude { get; init; }
public static GpsSettings Current;
}
...
// write
GpsSettings.Current = new GpsSettings {
UseGpsReceiver = true,
Latitude = 51.1234,
Longitude = 51.5678
};
// read
var gps = GpsSettings.Current;
var location = $"{gps.Latitude}, {gps.Longitude}";
// but never do this;
var location = $"{GpsSettings.Current.Latitude}, {GpsSettings.Current.Longitude}";
Not everyone would agree with me on this one but my personal approach would be to have a single dictionary of the following type:
Dictionary<string, object>
Wrapped in a separate class with the following methods such as AddValue, GetValue, HasKey, HasValue, and UpdateValue with lock statements. Also notice that you'll have to use somewhat generic methods in order to be able to retrieve the value with the actual type and a default value. For example:
public static T GetValue<T>(string key, T defaultValue)
Also, I don't see a problem with your approach but if you want to synchronize things then you'll need n dedicated locks for n dictionaries which I don't think is a clean way; unless I'm missing something, and of course registering multiple dictionaries in design time can be a headache.
Alternatively to using multiple ConcurrentDictionary<string, T> collections, or a single ConcurrentDictionary<string, object>, or the Locked<T> struct shown in Enigmativity's answer, you could just store the values in immutable and recyclable Tuple<T> instances, and store these in private volatile fields:
private static volatile Tuple<bool?> _UseGpsReceiver;
public static bool? UseGpsReceiver
{
get { return _UseGpsReceiver?.Item1; }
set { _UseGpsReceiver = new(value); }
}
private static volatile Tuple<string> _Latitude;
public static string Latitude
{
get { return _Latitude?.Item1; }
set { _Latitude = new(value); }
}
private static volatile Tuple<string> _Longitude;
public static string Longitude
{
get { return _Longitude?.Item1; }
set { _Longitude = new(value); }
}
Pros: Both the reading and the writing are lock-free. An unlimited number of readers and writers can read and update the values at the same time, without contention.
Cons: Every time a value is updated, a new Tuple<T> is instantiated, adding pressure on the .NET garbage collector. This reduces the appeal of this approach in case the values are updated too frequently. Also if you have dozens of properties like these, it might be easy to introduce subtle bugs by omitting the important volatile keyword by mistake.
One of our projects makes use of key-value pairs where certain runtime parameters - that do not change per instance of the program - determine the value gotten. For example:
Program run in test mode with the parameter "Municipal":
Key: "testMunicipalDirectory"
Value: "C:\Foo\Bar\"
Program run with the parameter "State":
Key: "StateDirectory"
Value: "C:\Bar\Baz\"
To make it slightly more complicated, if there is no matching key for, say "testMunicipalImagesDirectory", there is a fallback of "defaultImagesDirectory":
Key: "testMunicipalImagesDirectory" ?? "defaultImagesDirectory"
Value: "C:\Foo\Bar\Images" ?? "C:\Images"
Currently, there's a lot of code duplication/inefficiencies, and room for error. Every time one of these is referenced there's string concatenation and null-coalescing and other stuff going on.
It seems like this would benefit from a single-instance object that is passed certain parameters on initialization (test or not, "State" or "Municipal", etc), that will return the correct values for each different property the keys represent.
Many answers I found to questions asking how to use the singleton design pattern with parameters basically boil down to "if it uses parameters, you probably do not want a singleton". In my case, it is invalid to attempt to initialize the object with different values, and an exception should be thrown if this happens.
This is how I would accomplish this goal (pseudo-C#) (lazy-loading is not a requirement but is used here):
public sealed class Helper
{
// how can we enforce that Init has been called?
private static readonly Lazy<Helper> lazyLoader = new Lazy<Helper>(() => new Helper(name, test));
public static Helper Instance { get { return lazyLoader.Value; } }
public static void Init(string name, bool test)
{
// if it has already been initalized
throw new InvalidOperationException("This has already been initalized.");
// else initalize it
}
private string Name { get; set; }
private bool Test { get; set; }
private Helper(string name, bool test) { } // assign to properties, any other ctor logic
public string Directory
{ get { return ValueGetter.Get((this.Test ? "test" : "") + this.Name + "Directory"); } }
}
public static class ValueGetter
{
public static string Get(string key, string fallbackKey)
{
if (Keys.Any(k => k == key))
return Keys[key].Value;
else
return Keys[fallbackKey].Value;
}
}
But as you can see, there are questions remaining. How can it enforce calling Init before using the Instance, but not require those parameters to be passed every time Instance is accessed?
Is this the correct direction to go, or is there a better design pattern to use?
I'm beating my head against the wall pretty severely with this. I have several variables inside a C# console application that I would like to re-use. However, I cannot for the life of me re-use the variables in another class. I would love any help or pointers you could provide - I've searched for quite some time and I'm completely stumped.
EDIT: Yes, the variables are inside my Main function. Sorry for leaving this out.
EDIT: Heavily redacted code below. The variable values I'd like to re-use in another class are in the middle. There are more but those 3 should be sufficient for the sample. Thanks for the assistance!!!
public static class MyApp
{
static void Main(string[] args)
{
// loads XML doc
foreach (XmlNode node in nodes)
{
try
{
// does a bunch of stuff
// Parses variables from REST API
XDocument docdetailxml = XDocument.Parse(xmldoc);
XNamespace ns = docdetailxml.Root.GetDefaultNamespace();
var buid = docdetailxml.Root.Element(ns + "busid").Value;
var bname = docdetailxml.Root.Element(ns + "busname").Value;
var bcount = docdetailxml.Root.Element(ns + "buscount").Value;
// Invoke SQL connection string
// Trigger Stored Procedure and write values to database
// If needed, trigger email notification
// Close connections
}
catch (Exception e)
{
Console.WriteLine("Error encountered: " + e.Message);
// Exit the application
System.Environment.Exit(1);
}
finally
{
// Exit the application
// System.Environment.Exit(0);
}
}
}
private static void GetConnectionString()
{
throw new NotImplementedException();
}
private static void GetConnectionStrings()
{
throw new NotImplementedException();
}
}
}
you should define public property or public field
public class Student
{
public string Name {get;set;}
}
and when you want to pass value you can assign this value to property
Student st = new Student();
st.Name = "your value";
or you can use class constructor too.
If the variable denote some information about an object (like name, id, etc.) then they should be encapsulated in a class. The instance of the class (called an object) should be used to access this information.
As you already have the variables that represent an object, the next step would be to group these variables into classes. These variables are represented as properties in the class. The operations performed on these members should be available as methods. Furthermore the access modifiers decide the visibility of the members.
Going through your example, I can identify 3 variables that represent a Customer (assumption, I am not sure of the exact use case). These will form the Customer class.
class Customer
{
// You can either pass the UID through the constructor or
// expose a public setter to allow modification of the property
public Customer(string uid)
{
this.UID = uid;
}
public string UID { get; private set; }
public string Name { get; set; }
public string Count { get; set; }
}
Furthermore, the foreach loop can be split into 2 parts for resuablity
Read from the xml nodes and create a list of customers
Perform the database operations (like trigger stored procedures, write values, etc.) on the list of customers
Additionally, you can create another class that does the operations (business logic) that you are performing in the console application. This will allow you to reuse the same logic in case you move it to another application (like winforms or web service).
More information
Object oriented programming
Object oriented concepts in C#
Principles Of Object Oriented Design
I think there's a dedicated forum for struts on this site, best look there for more info.
Quick answer: the primary way of passing values from one action to another (I think you are working with struts Action classes?) is to put the values into the request or session (so, first job for you would be to read up on those topics: HttpServletRequest and HttpSession). Struts action classes do their work in the execute() method, and that method has a parameter of type HttpServletRequest. From the request you can get a handle to the session.
And both request and session offer methods getAttribute() and setAttribute(). So, to pass data from one action to another, set that data as a (request or session) attribute, then read out the attribute in the next action again.
The Program class is probably Static so you'll have to access those fields by class name instead of instance.
class Program
{
public string Name = "a name";
static void Main(string[] args)
{
Name = "Hello"; //You can't do this, compile error
Program p = new Program();
p.Name = "Hi"; //You can do this
SecondName = "Sn"; //You can do this
Program.SecondName = "Tr"; //You can do this too
}
public static string SecondName = "Peat";
}
How do I create a class library where I can get and set like the IIS Session object where I use var x = objectname("key") to get the value or objectname("key") = x to set the value?
Normally I just have a static class that wraps my session data and makes it type safe like:
public static class MySessionHelper
{
public static string CustomItem1
{
get { return HttpContext.Current.Session["CustomItem1"] as string; }
set { HttpContext.Current.Session["CustomItem1"] = value; }
}
public static int CustomItem2
{
get { return (int)(HttpContext.Current.Session["CustomItem2"]); }
set { HttpContext.Current.Session["CustomItem2"] = value; }
}
// etc...
}
Then when I need to get or set an item you would just do the following:
// Set
MySessionHelper.CustomItem1 = "Hello";
// Get
string test = MySessionHelper.CustomItem1;
Is this what you were looking for?
EDIT: As per my comment on your question, you shouldn't access the session directly from pages within your application. A wrapper class will make not only make the access type safe but will also give you a central point to make all changes. With your application using the wrapper, you can easily swap out Session for a datastore of your choice at any point without making changes to every single page that uses the session.
Another thing I like about using a wrapper class is that it documents all the data that is stored in the session. The next programmer that comes along can see everything that is stored in the session just by looking at the wrapper class so you have less chance of storing the same data multiple times or refetching data that is already cached in the session.
I guess, you could use a generic dictionary like Dictionary<string, Object> or something similar to achieve this effect. You would have to write some wrapper code to add an Object when accessing a non-existend item by for example a custom default property in your Wrapper.
You could use some thing like this
public class Session
{
private static Dictionary<string, object> _instance = new Dictionary<string, object>();
private Session()
{
}
public static Dictionary<string, object> Instance
{
get
{
if(_instance == null)
{
_instance = new Dictionary<string, object>();
}
return _instance;
}
}
}
And use it like this
Session.Instance["key"] = "Hello World";
I have a model program that represents message flow along a chain of servers:
public class MyModel
{
static bool x_send_msg1 = false; // has X sent msg1?
static bool y_recv_msg1 = false; // has Y received msg1?
static bool y_send_msg1 = false; // has Y sent msg1?
static bool z_send_msg1 = false; // has Z received msg1?
// (etc for more servers and more messages)
[Action]
static void YSendMsg1()
{
// Y sends Msg1 to Z
y_send_msg1 = true;
z_recv_msg1 = true;
}
static bool YSendMsg1Enabled()
{
// in the simplest case, this can happen whenever Y has received the
// message but not yet forwarded it
return y_recv_msg1 && !y_send_msg1;
}
}
There are lots more messages. The Enabled() logic for each server and message type is slightly different, but the state is similar, so I would like to encapsulate it by writing something more like:
class State
{
public bool send_msg1 = false;
public bool recv_msg1 = false;
}
public static State X = new State();
public static State Y = new State();
and then use the encapsulated state in my actions:
[Action]
static void YSendMsg1()
{
// instead of y_qqq above, now we can write Y.qqq:
Y.send_msg1 = true;
Z.recv_msg1 = true;
}
static bool YSendMsg1Enabled()
{
return Y.recv_msg1 && !Y.send_msg1;
}
However NModel won't let me use objects in this fashion to hold my state. Is there some other way I can avoid defining repeating groups of booleans, one for each server in the chain?
Questions of style aside, the main benefit of encapsulating the state as shown in the question is to reduce the amount of code that must be written and read. Instead of having to write (#servers * #messages) declarations, only (#server + #messages) are required.
The same reduction in code (with corresponding improvements in readability and reduction in carpal tunnel syndrome) can be achieved by using NModel's built-in Set class to track the state of each message. A set called send_msg1 contains the names of all the servers that have sent msg1:
public class MyModel
{
static set<int> send_msg1 = set<int>.EmptySet; // has server #n sent msg #1?
static set<int> recv_msg1 = set<int>.EmptySet; // has server #n received msg #1?
// (etc for more messages)
static int X = 1;
static int Y = 2;
// (etc for more server names)
[Action]
static void YSendMsg1()
{
// Y sends Msg1 to Z
send_msg1 = send_msg1.Add(Y);
recv_msg1 = recv_msg1.Add(Z);
}
static bool YSendMsg1Enabled()
{
// in the simplest case, this can happen whenever Y has received the
// message but not yet forwarded it
return recv_msg1.Contains(Y) && !send_msg1.Contains(Y);
}
}
(It is possible to reduce the amount of code event further, for example by using a map of sets to hold everything in a single variable. However one advantage of leaving the state patially separated is that it produces more legible state summaries in the model viewer.)
Since writing my answer above, I have learned of another solution that is closer to what I was originally looking for.
To use objects with instance variables, you can derive from LabeledInstance as shown below. The instances should be allocated using the static Create() method, and fields should be initialized in an overridden Initialize() method.
(You can also use instance methods for actions, but to do so you must assign a domain to the class; the name of that domain should correspond to a static set that contains all current instances of the class.)
Behind the scenes, NModel is going to translate this class into a bunch of maps, one for each instance variable in the class. The key into those maps will be indexed instances of the class name, e.g. State(1). This can be somewhat hard to read within the MVC tool, so you may also want to keep some kind of instance variable that contains a legible, consolidated summary of the object's state.
class State : LabeledInstance<State>
{
public override void Initialize()
{
send_msg1 = false;
recv_msg1 = false;
}
public bool send_msg1;
public bool recv_msg1;
}
public static State X = State.Create();
public static State Y = State.Create();
I think the observer pattern might help you here - http://www.dofactory.com/Patterns/PatternObserver.aspx