Click here to Skip to main content
15,885,133 members
Articles / Programming Languages / C++
Article

Application configuration file for applications

Rate me:
Please Sign up or sign in to vote.
3.46/5 (3 votes)
17 Oct 20043 min read 49.9K   502   20   7
Application configuration file for applications

Introduction

For Sample Application refer: http://www.codeproject.com/threads/BlackSabbatch.asp

Why do you need an Application configuration file?

Application configuration file can be compared to a Windows INI file. But XML being a modern standard and that a schema can be used to effortlessly validate these file makes it very attractive to use. Also an XML file gives more flexibility to structure, author and validate an application configuration file. My sample here uses MSXML parser. The class is thread safe. What I mean by thread safe is that, when used in a multi threaded project, the application configuration file will work fine. The extra task I had to do here was to Marshall the MSXML DOM COM object across threads.

XML
<?xml version="1.0" encoding="UTF-8" ?> 
<ApplicationConfig> 
  <Debug> <AppLogging> <BrokenLinksXMLFileName>
   C:\MyProjects\BlackSabbath\BlackSabbath.xml</BrokenLinksXMLFileName> 
  <BrokenLinksXMLSchemaFileName>BlackSabbathSchema.xml
    </BrokenLinksXMLSchemaFileName> <BrokenLinksXMLXSLTFileName>
 BlackSabbath.xsl</BrokenLinksXMLXSLTFileName> 
 <LogFileName>C:\MyProjects\BlackSabbath\BlackSabbath.log</LogFileName> 
  <CurrentLoggingLevel>1</CurrentLoggingLevel> </AppLogging> 
  </Debug> 
  <Release> <AppLogging> <BrokenLinksXMLFileName>
    C:\MyProjects\BlackSabbath\BlackSabbath.xml</BrokenLinksXMLFileName> 
  <BrokenLinksXMLSchemaFileName>BlackSabbathSchema.xml
  </BrokenLinksXMLSchemaFileName> 
  <BrokenLinksXMLXSLTFileName>BlackSabbath.xsl
  </BrokenLinksXMLXSLTFileName> 
 <LogFileName>C:\MyProjects\BlackSabbath\BlackSabbath.log</LogFileName> 
 <CurrentLoggingLevel>1</CurrentLoggingLevel> </AppLogging> 
</Release>
</ApplicationConfig> 

The above said file is BlackSabbathConfig.xml in the multithreaded sample provided at http://www.codeproject.com/threads/BlackSabbatch.asp. It has configuration settings for debug and release builds. Now the task is to write a reader class that is thread safe to access the configuration values. Since this is only a reader for a read only file, we don’t need a synchronization object to protect this class operation. The class name is CAppConfigReader and it is a singleton class, which has to be created and released once per application.

Creation

Can be done using a call of GetInstance() with the name of the configuration file.

// Get the application config file .. 
// Use registry or enviroment variable 
// in your applications
CAppConfigReader* pConfig = CAppConfigReader::GetInstance(
  "C:\\MyProjects\\BlackSabbath\\BlackSabbathConfig.xml");
ASSERT(NULL != pConfig);
VERIFY(NULL != pConfig);

Accessing from threads

Every subsequent call should not provide the file name, as it will result in reopening and loading the said file. The reason is because the implementation is singleton as there will be only one and only one application configuration file. If more configuration file reads needed, please change implementation from singleton to normal creation.

// Get the application config file
CAppConfigReader* pConfig = CAppConfigReader::GetInstance();
if(NULL != pConfig)
{
    // Get the logging level
    csLogLevel = pConfig->GetValue(("/AppLogging/CurrentLoggingLevel"));
    logLevelM = (eLoggingLevel)atoi(csLogLevel);
}

Initialize COM

COM has to be initialized on the thread trying to use this class as the DOM object is a COM object. MSXML4 dll is marked both and will work in Apartment threads and Free threads. Hence you can use OleInitialize(),CoInitialize(),CoInitializeEx(COINIT_APARTMENTTHREADED) for Apartment threading or CoInitializeEx (COINIT_MULTITHREADED) for Free threading. Free threaded initialization is faster and more efficient.

How to get a configuration Value

When you pass /AppLogging/LogFileName to pConfig->GetValue(), the function internally prefix Debug or Release as the build and makes it //Debug/AppLogging/LogFileName or //Release/AppLogging/LogFileName. The usage is as follows

CAppConfigReader* pConfig = CAppConfigReader::GetInstance();
if(NULL != pConfig)
{
  // Get the logging level
  csLogFileName = pConfig->GetValue(CString("/AppLogging/LogFileName"));
}

Releasing

COM interfaces are thread affinitive. What does this statement mean? COM interfaces belong to the thread that created and lives and dies with them. What if other threads needed to access this interface. The parent has to Marshall this interface to the other thread. What will happen if we just used this interface from a thread safe global variable? Everything will be fine, but when we access a method or property of this interface, COM will throw a RPC_E_WRONG_THREAD error. One of the standard functions available for marshalling purpose is CoMarshalThreadInterfaceInStream() and CoGetinterfaceAndReleaseStream(). These are old functions; we have an easy way to do this. IGlobalInterfaceTable referred to as GIT. This interface internally implements marshalling between threads.

Important: Only the thread that Created/Registered the interface can revoke it. This implies that the thread that created has to stay alive till revoked. Yes that's true. When the thread that created it dies, the interface also becomes invalid. So please make sure you call the CAppConfigReader::GetInstance("C:\\MyProjects\\BlackSabbath\\BlackSabbathConfig.xml" ) and CAppConfigReader :: Release from the same thread which will live till the end of the application. It should be preferably main thread. Single threaded application can use this without any worries. No need of using GIT in implementation either.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
I am a software programmer with 17 years of experience working on Microsoft technologies using various tools. Using spare time I play Ping Pong and enjoy music and movies.I come from Trichur, a town in kerala, India. I love code forums and feel obligated to contribute every once in a while.

I think Internet and the information share it provides is mind boggling. Do we ever believe, tomorrow always brings to reality,above and beyond what dreams can glimpse.

Comments and Discussions

 
QuestionAny Reason? Pin
Sreekanth Muralidharan12-Jan-07 0:47
Sreekanth Muralidharan12-Jan-07 0:47 
Is there any reason why this is better than using ini files or registry itself?

Sreekanth Muralidharan,
Corporate Systems Consultant [Embedded Systems],
INDIA

AnswerRe: Any Reason? Pin
Cheeran Santhosh9-Apr-09 14:51
Cheeran Santhosh9-Apr-09 14:51 
GeneralDefaults for configurations Pin
mef52627-Oct-04 11:50
mef52627-Oct-04 11:50 
GeneralRe: Defaults for configurations Pin
Cheeran Santhosh27-Oct-04 12:46
Cheeran Santhosh27-Oct-04 12:46 
GeneralRe: Defaults for configurations Pin
Cheeran Santhosh29-Oct-04 6:52
Cheeran Santhosh29-Oct-04 6:52 
GeneralRedundant Title Redundant Pin
armentage18-Oct-04 8:27
armentage18-Oct-04 8:27 
GeneralRe: Redundant Title Redundant Pin
Cheeran Santhosh21-Oct-04 22:14
Cheeran Santhosh21-Oct-04 22:14 

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.