I have the following situation. There is some very common class in my application that contains a static readonly field called "BinDirectory" that holds the path to the bin directory. Other fields in this class, which are static readonly too, use this value to as a base to their value. On the current version BinDirectory is initialized to hold the directory where the code is running (i.e. Assembly.GetExecutingAssembly().CodeBase). I want to extend this class to initialize BinDirectory to hold the "TargetDir" from the installer context when it is run from my application installer. I can change BinDirectory to be simply static but I don't want to, since it will make me do lots of changes to a class that is common in my app. Can somebody suggest an elegant solution to this problem?
Make it a property with just the "get" accessor:
public static string BinDirectory
{
get { return _initialisedBinDirectory; }
}
Then in your static constructor code, initialise the private variable as you need.
EDIT
Delayed load (as per comment):
public static string BinDirectory
{
get
{
if (_initialisedBinDirectory == null)
// load the variable when needed
else
return _initialisedBinDirectory;
}
}
This way you only load the variable when you need it, and it's re-used whenever you call it again. Hopefully you don't class null
as a valid value for it though.
It sounds like you're loath to change a static readonly field to simply static because it would force you to change the initialization of all of the other static readonly fields in your class.
If that is correct, unfortunately there isn't a whole lot you can do but take the time to make the change. By allowing the BinDirectory field to be set at runtime you are fundamentally changing the initialization sequence of the fields. Your code will need to adapt.
I think the easiest way is to convert to using static readonly properties which do the calculation of the value on the fly.
For example:
public class Values {
public static string BinDir;
public static string OtherDir {
get { return Path.Combine(BinDir,@"Some\Other\Path"); }
}
}
This is what AppConfigs are for. In your AppSettings section, add a new key called BinDirectory
. You can re-write your class as:
public static string BinDirectory
{
get
{
return ConfigurationManager.AppSettings["BinDirectory"];
}
}
Finally, as one of the last steps in your installation process, you can change the BinDirectory to point to any directory you want. So now this value is determined entirely by the installer context.