Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C#

Runtime variables class to support multiple application development

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
29 May 2012CPOL4 min read 12.3K   34   13   6
A runtime variables class to support multiple application development.

Introduction

Where I worked we had a number of applications that have a lot of projects in common. This includes having a number of forms that are the same. The problem was that the forms were the same, but slightly different (such as icons, titles, etc.). There were also other differences like the storage location of saved files, default file name, and the file extension.  Other differences included paths and file extensions.

Normally the Settings file is used to maintain this information, but there are two problems with the settings file: it is an internal class (this can be changed, but somewhat painful), and we did not want to modify the settings file when we were building the different applications. We also would do design using a combined set of projects where we would change the application by changing the startup project. The way we were solving this problem was a lot of custom code that had to figure out the actual application and make the changes. This is not very maintainable.

The solution was to put a static singleton in the common core project, a project shared by all applications, and referenced in all projects that needed access to the file. The trick was to make sure that the location did not cause circular references. Having a good location for this class was initially a problem because the design was not clean. After we fixed this problem, this solution worked like a charm.

The Design

The design centers on a class that contains a number of static properties that have a public Get and a protected Set. There is also a static constructor that sets the properties, and the class can be inherited.

C#
public class RuntimeVariables
{
 public static string Name { getprotected set; }
 
 static RuntimeVariables()
 {
    Name = "Test1";
 }
}

Here I have only a single static property, Name, but there can be many more.

Having a static constructor that sets the properties means that there is a default behavior. This was important for us because we were able minimize the changes for the legacy applications to just referring to the static properties instead of dealing immediately with possibly unknown side effects. The properties have a protected Set means that these variables cannot be changed except from a derived class.

The way to change these properties is to have a derived class that has a constructor that updates the properties as so:

C#
class RuntimeVariablesDerived : RuntimeVariables
{
 public RuntimeVariablesDerived()
 {
    Name = "Test2";
 }
}

To set these application variables, all that is needed for WPF is to have the App class create an instance of the derived runtime variables class:

C#
public partial class App : Application
{
 public App()
 {
    new RuntimeVariablesDerived();
 }
}

Just creating the instance will cause the instance constructor to run, setting all the static properties. Not perfect, but only have to set the values in one place, the derived class. This has reduced the maintenance significantly on our applications, and has made it easier to spin off new versions of the application (of course there were some bad decisions made during the design that made the situation worse than it should have been).

There are a number of variations on how this can be implemented. Since we were working with a legacy application, we used default values, but that may not have been the right choice. I now think that throwing an exception if a value that has not been initialized is useful in at least some cases. This would involve having a bool static variable in the base class that is set by the derived class, and then checked before returning any values:

C#
public string ProtectedName
{
 get
 {
   Check();
   return _protectedName;
 }
 protected set { _protectedName = value; }
}

private void Check()
{
 if (!ValuesSet)
    throw new NotInitiatedException("Application level constants have not been set");
}

The NotInitiatedException is a new class derived from Exception.

My implementation is not what was considered kosher by another developer, and he changed the implementation so that there is a method to update the value and not a derived class. This allowed the setter to become private. The method in the base class would look like this:

C#
public void SetName(string name)
{
 Name = name;
}

The Sample

The sample included with this article is extremely basic. The window only has a single element:

XML
<TextBlock Text="{Binding Name,Source={StaticResource runtimeVariables}}" 
           FontSize="14"/>

Without any change you see the value that is provided by the derived class. To see this change, you have to change the code. In the App.xaml.cs, there is the following:

C#
public partial class App : Application
{
  public App()
  {
    new RuntimeVariablesDerived();
  }
}

Just comment out “new RuntimeVariablesDerived()” and you will see the default value in the window. Otherwise the value will be that provided by the derived class.

Conclusion

This is not what I would prefer since I really would like to have something where I could better protect these values (make them read-only), but the protection is not bad, especially since there is no way to change the values through the properties. A nice thing about the design is that a “testing” derived class can be used, and properties can be added to set the application into a better environment for unit testing. This can normally be quite a challenge without proper forethought. What would have been really nice is if the static constructor could be made protected, then it would not be possible to use a static property without there being an instantiated class.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
GeneralMy vote of 5 Pin
A.J.Wegierski29-May-12 18:43
A.J.Wegierski29-May-12 18:43 
GeneralMy vote of 1 Pin
abdurahman ibn hattab29-May-12 10:10
abdurahman ibn hattab29-May-12 10:10 
GeneralRe: My vote of 1 Pin
Clifford Nelson29-May-12 11:42
Clifford Nelson29-May-12 11:42 
So how would you accomplish the same thing??
QuestionThe sample included with this article is extremely basic...?! Pin
VallarasuS29-May-12 6:21
VallarasuS29-May-12 6:21 
AnswerRe: The sample included with this article is extremely basic...?! Pin
Clifford Nelson29-May-12 9:33
Clifford Nelson29-May-12 9:33 
AnswerRe: The sample included with this article is extremely basic...?! Pin
Clifford Nelson29-May-12 11:45
Clifford Nelson29-May-12 11:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.