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";
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.
Okay, I am way outside my comfort zone here and am struggling with new concepts but I hope I can make myself clear.
As I understand it, global variables are very bad in C# (and are dangerous in general) but I don't really want to get into that debate. After some research I am led to believe that Singletons can help. Please feel free to offer alternatives here if that is wrong with the situation I describe below.
What I am trying to do is create a dynamic multi-dimensional array which will contain numerical data. This matrix will be varying in size and must be created during runtime (I am pulling data from a logging device through a GUI).
What I see being a solution is to create a class which has a variable which can I can get and set but with a dynamic size.
public class mySingleton
{
public static int dataSize { get; set; }
public double[] dataSet = new double[dataSize] { get; set; }
}
Something to this effect but obviously this is wrong and does not work. I have been trying to research how to initialize an array at runtime but cannot figure it out, but I also feel like I don't know which terms to search. Any help?
What you probably want to do is use explicit (rather than implicit) backing fields so that you can add logic to your getter and setter. Something like this:
public class mySingleton
{
private static int _dataSize; // you might want to set this to some sensible default
public static int DataSize
{
get { return _dataSize; }
set
{
_dataSize = value;
_dataSet = null; // changing the size will implicitly clear the array - but you could write code to resize if you really wanted to
}
}
private static double[] _dataSet;
public static double[] DataSet
{
get
{
if (_dataSet == null)
{
_dataSet = new double[_dataSize];
}
return _dataSet;
}
// you can include a setter if you want to let the consumer set the dataset directly - in which case it should update the _dataSize field.
}
}
You may want to initialize the array in response to the set method on your dataSize property. You won't be able to use the quick "autofill" properties ("get; set;"), but that way you will be able to initialize the data set as soon as a user sets the data size.
So something like this:
public class mySingleton
{
private static int _dataSize;
public static int dataSize {
get {return _dataSize;}
set {
_dataSize = value;
dataSet = new double[value];
}
}
public double[] dataSet { get; private set; }
}
In general, to set a static property of a class, you can use a static constructor (http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx) or control the flow of access to the class/data in a way that you can set up the static members before someone else needs to use them.
You can create an array of dynamic size easily:
double[] array = new double[size];
size can be any arbitrary expression of type int. So your code would look like this:
class ArrayHolder { public static double[] Value; } //global state
//set the global state somewhere else in your code:
var size = DetermineSize();
double[] array = new double[size];
ArrayHolder.Value = array; //publish globally
After having initialized the array it is available in the entire program. Arrays are reference types so there is no needless data copying here.
Sidenote: Why would you prefer a singleton to a static variable? Often they have the same pros and cons (IOW no meaningful difference). In my example I just used a static variable.
I am not sure if a Singleton suits best for your approach, but anyway, here is a Singleton Implementation:
public class MatrixSingleton
{
private static readonly MatrixSingleton instance = new MatrixSingleton();
static MatrixSingleton()
{
}
private MatrixSingleton()
{
this.Data = new List<Tuple<double, double>>();
}
public static MatrixSingleton Instance
{
get { return instance; }
}
public List<Tuple<double, double>> Data;
}
and the using of it
MatrixSingleton matrixSingleton = MatrixSingleton.Instance;
matrixSingleton.Data.Add(new Tuple<double, double>(1.1, 2.2));
For more information about the Singleton pattern these links might help:
http://braindrivendevelopment.com/2013/05/04/simplify-singleton-pattern/
http://www.csharpindepth.com/Articles/General/Singleton.aspx
I'm building an intranet using C# webforms. I've got a list object with a bunch of users which I'm cacheing. I'm trying to create a constructor that will do the following when I reference MainADList:
if it exists in the cache and is not null, use it
else generate the list and cache it
I've got the code to do the caching and retrieving, but it isn't encapsulated nicely in a way that I'd like.
public Users MainADList = new Users();
private void GenerateADList()
{
MainADList = (Users) Cache["MainADList"];
if (MainADList == null || MainADList.Count == 0)
{
//generate the list....
Cache["MainADList"] = MainADList;
}
}
Thanks!
You can't create a constructor which does that. A constructor always creates a new object.
Instead, create a static factory method:
public static Users GetUsers()
{
// Consult the cache, and create a new instance if necessary.
}
This may be a singleton - but it certainly doesn't have to be. (I wouldn't artificially impose its singleton-ness unless I really had to. I'm not a big fan of the singleton pattern.)
Alternatively, instead of a static factory method, you could have an instance method in a factory class:
public class UsersFactory
{
// Construct it with a cache, or whatever's required
public Users GetUsers()
{
// Use the cache, or construct a new value.
}
}
Now this is more testable - because you're not relying on any static (global) state. Instead, you can create a new factory from a new cache in each test.
In all of these solutions, you need to consider what threading behaviour you want. If you want to make sure that you only construct the value once, you'll need to use Lazy<T>, static initializer guarantees, or locking.
One general pattern you could follow:
public class ClassName {
public static Object CachedObject {
get {
Object o = (Object)Cache['CacheKey'];
if (o == null)
{
o = GetData();
Cache["CacheKey"] = o;
}
return o;
}
}
}
And treat ClassName.CachedObject as though it's always, eternally, and magically populated.
What you want is known as a Singleton.
Basically what you should do with the code you already have is something like this:
public static GetList
{
get
{
//check if list exists and create it - so basically call your private constructor
//return cached list
}
}
I have a class definition in which a readonly member is defined.
private readonly Dictionary<string, string> map = new Dictionary<string, string>();
Now in order to test my design, I want to access this member outside its class definition. I was thinking of providing a get method but unable to write an error free syntax.
Is it possible to assign value to a member(using new) and still able to define its get method?
PS: I am new to C# language.
EDIT:
I have not written the code, its just a statement I have copied from an already written module. I have made some design changes in the module and want to test it with minimal changes possible in the code, so for that I was looking to get the readonly access of this member outside the class.
You can define a read-only property for permitting public access to your field:
private readonly Dictionary<string, string> map =
new Dictionary<string, string>();
public Dictionary<string, string> Map
{
get { return map; }
}
Note that this will only prevent external classes from changing the instance reference assigned to map, not from changing the content of the dictionary itself.
One could argue that you shouldn't write tests for private members of a class. Tests should only use the public interface and don't rely on the internals of the class, since you should be able to refactor internals of the class without breaking any tests.
If you add a public getter 'only for testing' there's no guarantee that someone will start using somewhere in the project.
If you really want to expose the dictionary and use .NET 4.5, use ReadOnlyDictionary class to make sure that the caller won't change anything.
public IDictionary<string, string> Map
{
get { return new ReadOnlyDictionary<string, string>(map); }
}
Just create a simple getter
public Dictionary<string, string> Mapping
{
get { return map; }
}
You mean something like this?
readonly Dictionary<string, string> _map = new Dictionary<string, string>();
public Dictionary<string, string> Map
{
get { return _map; }
}
Why are you making this variable readonly?
If you're trying to give access to the values contained in the dictionary you could create a method that exposes the dictionary without allowing it to be modified:
public string GetMapValue(string key)
{
return _map[key];
}
You could write a public property function to return the private readonly map, e.g:
public Dictionary<string, string> Map { { get { return map; } } }
However, the Dictionary is still mutable. If you want a read-only Dictionary, see this SO question.
Like we do Session.Add("LoginUserId", 123);
and then we can access Session["LoginUserId"], like an Array, how do we implement it?
You need an indexer:
public Thing this[string index]
{
get
{
// get the item for that index.
return YourGetItemMethod(index)
}
set
{
// set the item for this index. value will be of type Thing.
YourAddItemMethod(index, value)
}
}
This will let you use your class objects like an array:
MyClass cl = new MyClass();
cl["hello"] = anotherObject;
// etc.
There's also a tutorial available if you need more help.
Addendum:
You mention that you wanted this to be available on a static class. That get's a little more complicated, because you can't use a static indexer. If you want to use an indexer, you'd need to access it off of a static Field or some such sorcery as in this answer.
You should use indexers
See the link:
http://msdn.microsoft.com/en-us/library/2549tw02.aspx
Sounds like all you need is a generic dictionary.
var session = new Dictionary<string, object>();
//set value
session.Add("key", value);
//get value
var value = session["key"] as string;
If you want to make this static, just make it a static member in another class.
public static class SharedStorage
{
private static Dictionary<string, object> _data = new Dictionary<string,object>();
public static Dictionary<string, object> Data { get { return _data; } }
}
Then you can access it as such, without having to initialize it:
SharedStorage.Data.Add("someKey", "someValue");
string someValue = (string) SharedStorage.Data["someKey"];
If you want to be more adventurous and are using .NET 4 you can also use an Expando Object, like the ViewBag member available to controllers in ASP.NET MVC 3:
dynamic expando = new ExpandoObject();
expando.UserId = 5;
var userId = (int) expando.UserId;
With the way you usually use the Session variable all you really need is a generic Dictionary collection like this one. You don't really need to write a class. But if you need to add extra functionality and/or semantics you could certainly wrap the collection with a class and just include and indexer.
For other collections check out the Collections.Generic namespace.