I have an ASP.NET MVC app. I need a Dictionary<string, string> that is available throughout the entire app at runtime. My question is, where is the best place/way to define this Dictionary? I assume I need to do it in the Global.asax file. Yet, I'm not sure.
Create a utility class and use Lazy to pospone intialization until the first hit:
public static class InfoHelper
{
private static Lazy<ConcurrentDictionary<string, string>> infoBuilder
= new Lazy<ConcurrentDictionary<string, string>>( () => SomeCreationMethod() );
public static ConcurrentDictionary<string, string> Info
{
get
{
return infoBuilder.Value;
}
}
Or, using HttpContext.Cache:
public static class InfoHelper
{
public static ConcurrentDictionary<string, string> Info
{
get
{
ConcurrentDictionary<string, string> d
= HttpContext.Current.Cache["someId"] as ConcurrentDictionary<string, string>;
if (d == null)
{
d = HttpContext.Current.Cache["someId"] = SomeCreationMethod();
}
return d;
}
}
Or, when setting this from an external class:
public static class InfoHelper
{
public static ConcurrentDictionary<string, string> Info
{
get
{
return HttpContext.Current.Cache["someId"] as ConcurrentDictionary<string, string>;
}
set
{
HttpContext.Current.Cache["someId"] = value;
}
}
Then set it from another class:
InfoHelper.Info = ...;
Related
I have a class, with some global and constant dictionaries. Like:
public static class Constants
{
public static Dictionary<string, MyObject> MyDictionary= new Dictionary<string, MyObject>()
{
{"first", new MyObject()},
{"second", new MyObject()},
};
}
Lets say I would like another dictionary, to be like that only with some added and removed elements. Is there a way to achieve that, within the static class? I imagine something like:
public static Dictionary<string, MyObject> MyOtherDictionary = MyDictionary.Remove("second").Add("Third", new MyObject())
But I know that does not work, so is there any way I can achieve this?
No, that doesnt work in this way for two reasons:
Remove returns a bool, you can't use Add on a bool
even if you make it compile, you don't want to modify the other dictionary but you want to create a new dictionary which contains similar items, you can use the constructor:
public static Dictionary<string, MyObject> MyOtherDictionary;
// ...
static Constants
{
MyOtherDictionary = new Dictionary<string, MyObject>(MyDictionary);
MyOtherDictionary.Remove("second");
MyOtherDictionary.Add("Third", new MyObject());
}
You could do it using properties instead
public static class Constants
{
public static Dictionary<string, MyObject> myDictionary
{
get
{
return new Dictionary<string, MyObject>()
{
{ "first", new MyObject()},
{ "second", new MyObject()},
};
}
}
static Dictionary<string, MyObject> _myOtherDictionary;
public static Dictionary<string, MyObject> myOtherDictionary
{
get
{
_myOtherDictionary = myDictionary;
_myOtherDictionary.Remove("first");
_myOtherDictionary.Add("third", new MyObject());
return _myOtherDictionary;
}
}
}
Title says it all. Reducing access through access modifiers only prevents reinitialising the property; It doesn't prevent elements from becoming global state (bad practice). I know there's a workaround with List<T>'s but what should I do for any other indexed collection?
public class Start
{
public static void main()
{
//CODE SMELL AHEAD
AttendanceManager.MuteStatuses[0] = new KeyValuePair <string, string> ("", "");
}
}
public static class AttendanceManager
{
public static HybridDictionary MuteStatuses
{
get
{
playersMuteStatuses.Add ("", "");
return playersMuteStatus;
}
}
private static HybridDictionary playersMuteStatus = new HybridDictionary();
}
Dont use HybridDictionary. We do have IReadOnlyDictionary<T>
private Dictionary<string, string> playersMuteStatus = new... ;
public IReadOnlyDictionary<string, string> MuteStatuses
{
get
{
return playersMuteStatus as IReadOnlyDictionary<string, string>;
}
}
Write helper methods:
public static void AddMuteStatus()
=> playersMuteStatus.Add("", "");
public static object GetMuteStatus(object idx)
=> return playersMuteStatus[idx];
I have a class like:
public class Something
{
private Dictionary<int,int> dic;
public Something()
{
dic = new Dictionary<int,int>();
}
public Something(Dictionary<int,int> a)
{
dic = new Dictionary<int,int>();
}
}
How can I avoid initializing the collection twice?
I guess you are looking for chaining constructor:
public class Something
{
private Dictionary<int, int> dic;
public Something()
: this(new Dictionary<int, int>())
{
}
public Something(Dictionary<int, int> a)
{
dic = a;
}
}
Call this():
public Something()
{
dic = new Dictionary<int,int>();
}
public Something(Dictionary<int,int> a) : this()
{
// do something with a??
}
note that the "default" constructor is NOT called by default form other constructors, so you're not really initializing the dictionary twice.
There is another alternative:
public class Something
{
private Dictionary<int, int> dic;
private void Initialize()
{
dic = new Dictionary<int, int>();
}
public Something()
{
Initialize();
}
public Something(Dictionary<int, int> a)
{
Initialize();
// do something with a??
// Yes, you are not using the parameter "a".
// I don't know if this is intentional.
}
}
Note: this wont work for readonly fields.
By the way, as I mentioned you can chain the constructors. The compiler can optimize it.
I want to implement a wrapper class for a Dictionary that maps a Type to a generic List of that Type. For example:
**Key** **Value**
typeof(InterfaceA), List<InterfaceA>
typeof(InterfaceB), List<InterfaceB>
typeof(MyClass), List<MyClass>
...
I then want to interact with the wrapper class by using types.
public void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry<T>()
{
return MyDict[typeof(T)];
}
public void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
Is there any elegant way to do this?
EDIT: to clarify, the point of this is so that with
GetEntry<MyInterface>()
the items in the list are guaranteed to follow the contract of MyInterface. Each entry would have a different Type key, and each List of items would follow the contract of that Type.
You could use the following static class
public static class GenericLists
{
private static Dictionary<Type, object> MyDict = new Dictionary<Type, object>();
public static void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public static List<T> GetEntry<T>()
{
return (List<T>)MyDict[typeof(T)];
}
public static void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
}
Or you could use
public class GenericLists<T>
{
private Dictionary<Type, List<T>> MyDict = new Dictionary<Type, List<T>>();
public void NewEntry()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry()
{
return MyDict[typeof(T)];
}
public void RemoveEntry()
{
MyDict.Remove(typeof(T));
}
}
if you really want to initialize it, but I think the static will work better.
If you're willing to store everything statically, you can use the type system:
static class MyDict {
private static class Data<T> {
public static readonly List<T> items = new List<T>();
}
public static List<T> Get<T>() { return Data<T>.items; }
public static void Add<T>(T item) { Data<T>.items.Add(item); }
}
Note that this makes it impossible to remove a key (you can't unload a type), although you can Clear() it.
You can do it as an instance-based class also (see below), but my preference, if it works for you, is to use a static variable in a static class as SLaks demonstrated in the "use the type system" post.
public class GenericTypeListDictionary
{
private readonly Dictionary<Type, object> _dictionaryOfLists = new Dictionary<Type, object>();
public List<T> NewEntry<T>()
{
var newList = new List<T>();
_dictionaryOfLists.Add(typeof(T), newList);
return newList;
}
public List<T> GetEntry<T>()
{
object value;
if (_dictionaryOfLists.TryGetValue(typeof(T), out value))
{
return (List<T>)value;
}
return null;
}
public void RemoveEntry<T>()
{
_dictionaryOfLists.Remove(typeof(T));
}
}
I have a class in C# that contains a Dictionary, which I want to create and ensure nothing as added, edited or removed from this dictionary as long as the class which contains it exists.
readonly doesn't really help, once I tested and saw that I can add items after. Just for instance, I created an example:
public class DictContainer
{
private readonly Dictionary<int, int> myDictionary;
public DictContainer()
{
myDictionary = GetDictionary();
}
private Dictionary<int, int> GetDictionary()
{
Dictionary<int, int> myDictionary = new Dictionary<int, int>();
myDictionary.Add(1, 2);
myDictionary.Add(2, 4);
myDictionary.Add(3, 6);
return myDictionary;
}
public void Add(int key, int value)
{
myDictionary.Add(key, value);
}
}
I want the Add method not to work. If possible, I want it not to even compile. Any suggestions?
Actually, I'm worried for it is code that will be open for a lot of people to change. So, even if I hide the Add method, it will be possible for someone to "innocently" create a method which add a key, or remove another. I want people to look and know they shouldn't change the dictionary in any ways. Just like I have with a const variable.
Hide the Dictionary totally. Just provide a get method on the DictContainer class that retrieves items from the dictionary.
public class DictContainer
{
private readonly Dictionary<int, int> myDictionary;
public DictContainer()
{
myDictionary = GetDictionary();
}
private Dictionary<int, int> GetDictionary()
{
Dictionary<int, int> myDictionary = new Dictionary<int, int>();
myDictionary.Add(1, 2);
myDictionary.Add(2, 4);
myDictionary.Add(3, 6);
return myDictionary;
}
public this[int key]
{
return myDictionary[key];
}
}
Don't define the Add Method.
Keep the myDictionary variable private and expose a Getter/Indexer so that it can only be read from outside that class..
There's no built-in way to do that, consider using a wrapper class.
interface IReadOnlyDic<Key, Value>
{
void Add(Key key, Value value);
}
class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>, IReadOnlyDic<Key, Value>
{
public new void Add(Key key, Value value)
{
//throw an exception or do nothing
}
#region IReadOnlyDic<Key,Value> Members
void IReadOnlyDic<Key, Value>.Add(Key key, Value value)
{
base.Add(key, value);
}
#endregion
}
to add custom items;
IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
if (dict != null)
dict.Add(1, 155);
and this is another way
class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>
{
private bool _locked = false;
public new void Add(Key key, Value value)
{
if (!_locked)
{
base.Add(key, value);
}
else
{
throw new ReadOnlyException();
}
}
public void Lock()
{
_locked = true;
}
}
FYI, now it is built-in to .net 4.5.
http://msdn.microsoft.com/en-us/library/gg712875(v=vs.110).aspx
Similar to Neil's answer:
Hide the Dictionary totally. Just provide a get method on the DictContainer class that retrieves items from the dictionary. If you want to use [] override you need getter settter method (atleast any one get/set)
public class DictContainer
{
private readonly Dictionary<int, int> myDictionary;
public DictContainer()
{
myDictionary = GetDictionary();
}
private Dictionary<int, int> GetDictionary()
{
Dictionary<int, int> myDictionary = new Dictionary<int, int>();
myDictionary.Add(1, 2);
myDictionary.Add(2, 4);
myDictionary.Add(3, 6);
return myDictionary;
}
public this[int key]
{
get => myDictionary[key];
}
}