Reputation: 67
I want to create a dictionary from a settings file that is formatted as a list of strings "somekey = somevalue". I then want this dictionary of keys and values, generated by one class, to be available to other classes in my program, so I don't have to refer back to the external file every time I want to use the settings in another class.
I've figured out the first part, creating a class that can read an external file and convert the list of strings into a dictionary, but I can't figure out how to make the dictionary data created by the file-reading class available to other classes in the same namespace.
Upvotes: 5
Views: 1936
Reputation: 26267
A little different approach would be to use an extension method, my example is rather basic but it works perfectly
using System.Collections.Generic;
namespace SettingsDict
{
class Program
{
static void Main(string[] args)
{
// call the extension method by adding .Settings();
//Dictionary<string, string> settings = new Dictionary<string, string>().Settings();
// Or by using the property in the Constants class
var mySettings = Constants.settings;
}
}
public class Constants
{
public static Dictionary<string, string> settings
{
get
{
return new Dictionary<string, string>().Settings();
}
}
}
public static class Extensions
{
public static Dictionary<string, string> Settings(this Dictionary<string, string> myDict)
{
// Read and split
string[] settings = System.IO.File.ReadAllLines(@"settings.txt");
foreach (string line in settings)
{
// split on =
var split = line.Split(new[] { '=' });
// Break if incorrect lenght
if (split.Length != 2)
continue;
// add the values to the dictionary
myDict.Add(split[0].Trim(), split[1].Trim());
}
return myDict;
}
}
}
Contents of settings.txt
setting1=1234567890
setting2=hello
setting3=world
And the result
You should of course extend this with your own protective features and similar. This is an alternative approach but using extension methods is not that bad. The functionality in the Extensions class can also be implemented directly in the property method in the Constants class. I did that for the fun of it :)
Upvotes: 1
Reputation: 12574
Im not really sure what your getting at here. Cant you simply make the dictionary a public property of that class?
Ok one option is to use a public property and then create one instance of that class when you initialise your application (this will populate your dictionary if you make it populate in your classes constructor) and then you can pass that same instance into functions or class constructors without having to read the external file again.
public class ReadFileClass
{
//Can be replaced with auto property
public Dictionary<string, string> Settings
{
Get{return Settings}
Set{Settings = value}
}
public ReadFileClass()
{
//In this constructor you run the code to populate the dictionary
ReadFile();
}
//Method to populate dictionary
private void ReadFile()
{
//Do Something
//Settings = result of doing something
}
}
//First class to run in your application
public class UseFile
{
private ReadFileClass readFile;
public UseFile()
{
//This instance can now be used elsewhere and passed around
readFile = new ReadFileClass();
}
private void DoSomething()
{
//function that takes a readfileclass as a parameter can use without making a new instance internally
otherfunction(readFileClass);
}
}
By doing the above you can use just one instantiation of an object to populate the settings dictionary and then simply pass it around. I have used this method many times to avoid making multiple round trips to a database or a file that can have costly performance impact. If you want to use the class containing the settings in another file other than the one that instantiates it you simply makes the classes constructor take it as a parameter.
Upvotes: 1
Reputation: 23833
Just make the class that constins the dictoionary public and the dictionary in that class static, so
public class MyClass
{
// ...
public static Dictionary<string, string> checkSumKeys { get; set; }
// ...
}
call this like
// ...
foreach (KeyValuePair<string, string> checkDict in MyClass.checkSumKeys)
// Do stuff...
Or, if the dictionary is not made static you will have to instantiate the class
public class MyClass
{
// ...
public Dictionary<string, string> checkSumKeys { get; set; }
// ...
}
call this like
MyClass myclass = new MyClass();
foreach (KeyValuePair<string, string> checkDict in myClass.checkSumKeys)
// Do stuff...
I hope this helps.
Upvotes: 1