Tag Archives: type-safe

Cinchoo – Configuration framework, part 16

Configuration Meta Data Information

In this section I’m going to talk about Configuration Meta Data, a self described information about individual configuration object. This data used to control the behavior of the configuration object at any time (even at run time).

It can be controlled either by declarative or configuration.

First, I’ll discuss about specifying meta-data by declarative manner

Declarative Approach

All the configuration object must be decorated by ChoConfigurationSectionAttribute or one of the derived attributes.

  • BindingMode – Direction of configuration data flow.
    • TwoWay updates the target property or the property whenever either the target property or the source property changes. Default.
    • OneWay updates the target property only when the source property changes.
    • OneTime updates the target property only when the application starts.
    • OneWayToSource updates the source property when the target property changes.
  • Defaultable – true, will create the the section in the underlying configuration file if not present. Default is true.
  • ConfigStorageType – Type of the underlying configuration storage. Please visit Available Configuration Section Handlers for list of available storages.
  • ConfigFilePath – Absolute or relative file path to configuration file used by the configuration object.
  • ConfigFileNameFromTypeName – Configuration file name from Type name.
  • ConfigFileNameFromTypeFullName – Configuration file name from Type full name.
  • LogCondition – true, to allow log anything to the underlying log file using ConfigurationObject Log() method. Default value is true.
  • LogDirectory – Absolute or related path of the log directory. Default value is [Frameworklogdirectory]\Settings folder.
  • LogFileName – Log file name. Default value is Configuration Object Type full name.
  • LogTimeStampFormat – Log entry time stamp format. Default value is “yyyy-MM-dd hh:mm:ss.fffffff”.
  • Parameters – Reserved
  • Silent – true, will ignore any error while loading configuration parameters. Default is true.

Below is the sample configuration object decorated with meta-data information

[ChoConfigurationSection("applicationSettings", ConfigFileNameFromTypeName = typeof(SampleConfigSection), BindingMode = ChoConfigurationBindingMode.OneWay, LogDirectory = @"C:\Logs")]
public class SampleConfigSection : ChoConfigurableObject
{
	#region Instance Data Members (Public)

	[ChoPropertyInfo("name", DefaultValue="Mark")]
	public string Name;

	[ChoPropertyInfo("message", DefaultValue="Hello World!")]
	public string Message;

	#endregion
}

When you instantiate and use the above configuration object in your application, Cinchoo framework creates meta-data section in the meta-data file ([appExeName].config.meta) as below

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <applicationSettings bindingMode="OneWay" defaultable="true" silent="true">
    <logInfo condition="true" directory="Settings" fileName="SampleConfigSection.log" />
  </applicationSettings>
</configuration>

Configuration Approach

Cinchoo framework creates or uses the meta-data information in [appExeName].config.meta file by default.

This file name can be overridden. Please visit Framework Configuration Parameters section on how to do it.

Once file has been created and used by the framework, you have a chance to modify them to control the configuration object at run-time. Any changes made to this file automatically picked up framework and adjust the meta-data accordingly. Do not require restart of the application.

Also for any reason you have doubt about the values in the meta-data file, you can let the framework auto correct them by simple delete the a section from the meta-data file. Try for yourself.

Advertisements

Cinchoo – Overriding Framework Configuration Parameters

In this section, I’ll go over the list of Cinchoo framework configuration parameters can be overridden to control the run-time environment of the framework either through configuration or programmatically.

Framework will run fine without overriding these parameters. Only when you need, you can override them. In those situation, it can be done through configuration or programmatically.

First, we will see how to override them through configuration. All the framework parameters must be stored in ChoCoreFrx.config file under application executable folder. This is the default behavior of discovering this file by the framework. But this can be overridden by specifying the path to this file through appFrxSettings custom configuration section in App.config file as below

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="appFrxSettings" type="Cinchoo.Core.ChoAppFrxSettings, Cinchoo.Core" />
    </configSections>
    <appFrxSettings appFrxFilePath="C:\ConfigFolder" />
</configuration>

GlobalApplicationSettings

There are the application level settings used by framework. Below are the attributes and their usages.

  • globalApplicationSettings – Global application parameters used by framework. All the variables are optional.
    • singleInstanceApp [bool] – true, to ensure there is only one instance of the application running at any point in time. false, lets you to run multiple instances of the application. Default is false.
    • applicationId [string] – the custom application name. Default value is the executable name.
    • eventLogSourceName [string] – Event log source name where all the errors are posted on this name, default value is applicationId.
    • useApplicationDataFolderAsLogFolder [bool] – true, it uses the current roaming user directory. Default is false.
    • logFolder [string] – A log directory, where all the log files are created by framework. Default is ‘[appExePath]\Logs’.
    • appConfigPath [string] – configuration file path. If not specified, this will be [appExeFolder].[appExeName].xml
    • logTimeStampFormat [string] – A time stamp format used when logging information to log files. Default value is “yyyy-MM-dd hh:mm:ss.fffffff”
    • traceLevel [int] – Specifies what message to output for the Trace/ChoTrace classes. 0-Off, 1-Error, 2-Warning, 3-Info, 4-Verbose.

Here is the sample Global Application Settings section in ChoCoreFrx.config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <globalApplicationSettings singleInstanceApp="false" applicationId="TestApplication" eventLogSourceName="TestApplication" useApplicationDataFolderAsLogFolder="false">
    <logFolder>C:\Logs</logFolder>
    <appConfigPath>c:\config\TestApplication.xml</appConfigPath>
    <logTimeStampFormat>yyyy-MM-dd hh:mm:ss.fffffff</logTimeStampFormat>
  </globalApplicationSettings>
</configuration>

MetaDataFilePathSettings

Cinchoo framework creates as well as uses number of Meta-Data files, these file paths can be configured through ChoCoreFrx.config file.

  • configurationMetaDataFilePath – meta data file path used by Configuration manager. By default, it’s value is [appExeName].config.meta
  • pcMetaDataFilePath – meta data file path used by Performance Counter manager. By default, its value is [appExeName].perf.meta

Here is the sample xml section looks like

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <metaDataFilePathSettings>
    <configurationMetaDataFilePath>c:\Config\configurationMetaFile.meta</configurationMetaDataFilePath>
    <pcMetaDataFilePath>c:\Config\PCMetaFile.meta</pcMetaDataFilePath>
  </metaDataFilePathSettings>
</configuration>

Run-Time approach

Lets see how we can override the system parameters at run-time in here. Cinchoo framework exposes ChoApplication.ApplyFrxParamsOverrides event. By subscribing to this event, you have a chance to override the framework parameters at run-time. See below the sample code on how to override some of the system parameters

static void Main(string[] args)
{
    try
    {
        ChoApplication.ApplyFrxParamsOverrides += new EventHandler<ChoFrxParamsEventArgs>(ChoApplication_ApplyFrxParamsOverrides);
        XmlApplicationSettings ApplicationSettings = new XmlApplicationSettings();
    }
    finally
    {
        ChoAppDomain.Exit();
    }
}

static void ChoApplication_ApplyFrxParamsOverrides(object sender, ChoFrxParamsEventArgs e)
{
    e.GlobalApplicationSettings.SingleInstanceApp = true;
    e.MetaDataFilePathSettings.ConfigurationMetaDataFilePath = @"C:\Config\MetaDataFilePath.meta";
}

Cinchoo – Configuration framework, part 15

Available Configuration Section Handlers

Here is the list of available configuration section handlers in Cinchoo framework. This list will keep changing based on the more support to other data sources. Keep looking for new configuration section handlers.

  • ChoNameValueSectionHandler (Default)

Cinchoo – Using Performance Counters, Part 4

This is the continuation of previous articles on Performance Counters. So far you learned how to create, use and control the performance counters in your application. In this article, I’ll talk about two performance counters category attributes to control the installation of  Performance Counters.

There are

  • selfInstall – true to install the counters automatically when you instantiate the object, otherwise it won’t install the counters.
  • recreate – true to recreate the counters irrespective of their existence, otherwise skip recreating them if already exists.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <PerformanceCounterCategory name="Random Single Instance Test" selfInstall="true" recreate="true">
    <PerformanceCounter name="Random Rate" turnOn="true" />
    <PerformanceCounter name="Random Average" turnOn="true" />
  </PerformanceCounterCategory>
  <PerformanceCounterCategory name="Random Multiple Instance Test" selfInstall="true" recreate="true">
    <PerformanceCounter name="Random Value" instanceName="Standard" turnOn="true" />
    <PerformanceCounter name="Random Value" instanceName="Inverted" turnOn="true" />
  </PerformanceCounterCategory>
</configuration>

Cinchoo – Using Performance Counters, Part 3

In this section, I’ll talk about installing and uninstalling Performance Counters using Cinchoo framework. This is the explicit way of installing and uninstalling them.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Instrumentation.Performance

For a sample performance counter class defined as below

[ChoPerformanceCounterCategory("Random Single Instance Test", PerformanceCounterCategoryType.SingleInstance)]
public sealed class SingleInstancePerfCounters : ChoPerformanceCounterCategory
{
    #region Performance Counters

    [ChoPerformanceCounter("Random Rate", "", PerformanceCounterType.RateOfCountsPerSecond32)]
    public readonly ChoPerformanceCounter PCRandomRate = null;

    [ChoPerformanceCounter("Random Average", "", PerformanceCounterType.AverageCount64)]
    public readonly ChoPerformanceCounter PCRandomAverage = null;

    #endregion
}

Installing Performance Counters

This is how to install the performance counter using ChoPerformanceCounterInstaller helper class

ChoPerformanceCounterInstaller.Install(typeof(SingleInstancePerfCounters))

Uninstalling Performance Counters

Here is how to uninstall the performance counter using ChoPerformanceCounterInstaller helper class

ChoPerformanceCounterInstaller.Uninstall(typeof(SingleInstancePerfCounters))

Cinchoo – Using Performance Counters, Part 2

This article is the continuation of previous one. So far you learned how to create and use performance counters in your application. In this section, I’ll show you how to control them through configuration.

Cinchoo framework generates meta data configuration file for all the performance counters you created in your application. This file will be created automatically in the application configuration folder. The file name will be [appExeName].perf.meta.

If you application executable name is HelloWorld.exe, this meta data file will be created in the name of HelloWorld.perf.meta. This is the default behavior.

This file name can be overridden. Please visit Framework Configuration Parameters section on how to achieve it.

For the samples from the previous sections, the meta data file will be created as below

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <PerformanceCounterCategory name="Random Single Instance Test">
    <PerformanceCounter name="Random Rate" turnOn="true" />
    <PerformanceCounter name="Random Average" turnOn="true" />
  </PerformanceCounterCategory>
  <PerformanceCounterCategory name="Random Multiple Instance Test">
    <PerformanceCounter name="Random Value" instanceName="Standard" turnOn="true" />
    <PerformanceCounter name="Random Value" instanceName="Inverted" turnOn="true" />
  </PerformanceCounterCategory>
</configuration>

PerformanceCounterCategory section will be created for corresponding performance counter category. A PerformanceCounter element will be created for each performance counter in the category.

At present, turnOn is the only fact used by the framework to enable or disable the counter. You can touch this attribute any time (run-time as well), application pick up the changes and act accordingly.

If turnOn is true, the performance counter will be enabled. Otherwise it is disabled. This feature helps you to control the performance counter in the production environment as Performance Counters will affect your application performance.

Cinchoo – Using Performance Counters, Part 1

In this section I’ll discuss about how we can use Cinchoo framework’s performance counter helper class to gather data from an application. So we will first understand the fundamentals and then we will see a simple example from which we will collect some performance data.

Before we begin, if you like to know more information about Performance Counter, please visit below links

MSDN Performance Counter Class

An Article on Performance Counter in CodeProject

Cinchoo framework provides nifty performance counter helper classes to makes it easier for developers to develop applications that use Performance Counter to monitor the health of the application.

There are two types of Performance Counter Categories

  • SingleInstance – The performance counter category can have only a single instance.
  • MultipleInstance – The performance counter category can have multiple instances.

Creating and using SingleInstance Performance Counters

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Instrumentation.Performance

[ChoPerformanceCounterCategory("Random Single Instance Test", PerformanceCounterCategoryType.SingleInstance)]
public sealed class SingleInstancePerfCounters : ChoPerformanceCounterCategory
{
    #region Performance Counters

    [ChoPerformanceCounter("Random Rate", "", PerformanceCounterType.RateOfCountsPerSecond32)]
    public readonly ChoPerformanceCounter PCRandomRate = null;

    [ChoPerformanceCounter("Random Average", "", PerformanceCounterType.AverageCount64)]
    public readonly ChoPerformanceCounter PCRandomAverage = null;

    #endregion
}
 Now lets see how to instantiate and use them
[STAThread]
static void Main(string[] args)
{
    SingleInstancePerfCounters perfCounter = new SingleInstancePerfCounters();

    Random rand = new Random(42);
    int randMax = 100;

    while (true)
    {
        int r = rand.Next(randMax);

        if (perfCounter.PCRandomRate != null)
            perfCounter.PCRandomRate.Increment();
        if (perfCounter.PCRandomAverage != null)
            perfCounter.PCRandomAverage.IncrementBy(r);

        Thread.Sleep(1000);
    }
}

Creating and using MultipleInstance Performance Counters

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Instrumentation.Performance

[ChoPerformanceCounterCategory("Random Multiple Instance Test", PerformanceCounterCategoryType.MultiInstance)]
public sealed class MultipleInstancePerfCounters : ChoPerformanceCounterCategory
{
    #region Performance Counters

    [ChoPerformanceCounter("Random Value", "", PerformanceCounterType.NumberOfItems64, "Standard")]
    public readonly ChoPerformanceCounter PCRandomValue;

    [ChoPerformanceCounter("Random Value", "", PerformanceCounterType.NumberOfItems64, "Inverted")]
    public readonly ChoPerformanceCounter PCRandomInvertedValue;

    #endregion
}

Please remember that the above two Performance counter members are given same category name ‘Random Value’ and different instance names. It qualifies them to create multiple instances of performance counters.

Now lets see how to instantiate and use them

[STAThread]
static void Main(string[] args)
{
    MultipleInstancePerfCounters perfCounter = new MultipleInstancePerfCounters();

    Random rand = new Random(42);
    int randMax = 100;

    while (true)
    {
        int r = rand.Next(randMax);

        if (perfCounter.PCRandomValue != null)
            perfCounter.PCRandomValue.RawValue = r;
        if (perfCounter.PCRandomInvertedValue != null)
            perfCounter.PCRandomInvertedValue.RawValue = randMax - r;

        Thread.Sleep(1000);
    }
}

In the next part, will see how to control the Performance Counters through configuration.

Cinchoo – Configuration framework, part 14

Configuration Objects Logs

Cinchoo framework creates a  log file for each configuration object separately. Those log files are created under application binary folder. By default the log file name are generated from configuration object type full name.

For a sample configuration object below

namespace HelloWorld
{
	#region NameSpaces

	using System;
	using Cinchoo.Core.Configuration;

	#endregion NameSpaces

	[ChoConfigurationSection("sample")]
	public class SampleConfigSection : ChoConfigurableObject
	{
		#region Instance Data Members (Public)

		[ChoPropertyInfo("name", DefaultValue="Mark")]
		public string Name;

		[ChoPropertyInfo("message", DefaultValue="Hello World!")]
		public string Message;

		#endregion
	}
}

The log file will be created in the name of HelloWorld.SampleConfigSection.log under Application Bin/Settings folder.

2012-03-19 05:18:47.7648110
  -- HelloWorld.SampleConfigSection State --
	Name: Mark
	Message: Hello World!

-- MetaData Information --
	BindingMode: TwoWay
	Defaultable: True
	IgnoreError: True
	ConfigurationMetaDataLogInfo:
		-- Log Information --
			Condition: True
			TimeStampFormat:
			TraceOutputDirectory: Settings
			TraceOutputFileName: HelloWorld.SampleConfigSection.log

	ConfigStorageType: Cinchoo.Core.Configuration.Storage.ChoFileNameValueConfigStorage, Cinchoo.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de

Application Log Folder can be overridden in both ways

  • Globally at the application level
  • Locally at each configuration object level

1. Overriding Global Log Folder

The application log folder can be overridden. Please visit Framework Configuration Parameters section on how to do it.

2. Overriding at individual configuration at object level

In some cases, you may want to redirect the log files of individual configuration object to some specific folder. In that moment, it can achieved as below.

namespace HelloWorld
{
	#region NameSpaces

	using System;
	using Cinchoo.Core.Configuration;

	#endregion NameSpaces

	[ChoConfigurationSection("sample", TraceOutputDirectory = @"C:\CustomLogsFolder")]
	public class SampleConfigSection : ChoConfigurableObject
	{
		#region Instance Data Members (Public)

		[ChoPropertyInfo("name", DefaultValue="Mark")]
		public string Name;

		[ChoPropertyInfo("message", DefaultValue="Hello World!")]
		public string Message;

		#endregion
	}
}

In this sample, we can route the log files of Configuration Object to C:/CustomLogsFolder directory using TraceOutputDirectory attribute member as below.

You can even override the individual configuration object log file through TraceOutputFileName attribute member as below

namespace HelloWorld
{
	#region NameSpaces

	using System;
	using Cinchoo.Core.Configuration;

	#endregion NameSpaces

	[ChoConfigurationSection("sample", TraceOutputDirectory = @"C:\CustomLogsFolder", TraceOutputFileName = "OverriddenSampleConfigObject.log")]
	public class SampleConfigSection : ChoConfigurableObject
	{
		#region Instance Data Members (Public)

		[ChoPropertyInfo("name", DefaultValue="Mark")]
		public string Name;

		[ChoPropertyInfo("message", DefaultValue="Hello World!")]
		public string Message;

		#endregion
	}
}

Cinchoo – Configuration framework, part 12

Using ChoFileXmlSerializerConfigStorage

Download sample source files (Require .NET 4.0 / Visual Studio 2010)

In this section, I’ll go over the details of using ChoFileXmlSerializerConfigStorage in your application. It’s a custom configuration section handler enables application to read and write application settings from configuration file in complex Xml format.

1. Define the configuration section object decorated with ChoXmlSerializerConfigurationSectionAttribute as below.

[ChoXmlSerializerConfigurationSection("sample")]
public class SampleConfigSection : ChoConfigurableObject
{
    #region Instance Data Members (Public)

    [XmlAttribute]
    public string Name;

    [XmlElement]
    public string Message;

    #endregion

    [ChoAfterConfigurationObjectLoadedHandler]
    void OnAfterConfigurationObjectLoaded(object sender, ChoConfigurationObjectEventArgs e)
    {
        Console.WriteLine(sender.ToString());
    }
}

2. Now instantiate and use it as below.

class Program
{
	static void Main(string[] args)
	{
		SampleConfigSection sampleConfigSection = new SampleConfigSection();
		Console.WriteLine(sampleConfigSection.ToString());
	}
}

The configuration section will be generated automatically for the first time in HelloWorld.exe.xml as below.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <sample Name="Mark">
    <Message>Hello World!</Message>
  </sample>
  <configSections>
    <section name="sample" type="Cinchoo.Core.Configuration.ChoXmlSerializerSectionHandler, Cinchoo.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de" />
  </configSections>
</configuration>

Cinchoo – Property Replacer, Part 2

Customizing Property Replacer – Dynamic Properties

We have learnt about defining and using static property in the previous section. In this section, I’m going to talk about defining and using Dynamic properties in your application. Dynamic properties are properties their values are resolved at the time of calling.

Below is the sample Property Replacer,

public class ChoDynamicPropertyReplacer : IChoKeyValuePropertyReplacer
{
    #region Instance Data Members

    private readonly Dictionary<string, string> _availPropeties = new Dictionary<string, string>()
        {
            { "HOME_PAGE", "Cinchoo framework website." },
            { "LAST_VISIT", "The last visit to the home page." }
        };

    #endregion Instance Data Members

    #region IChoKeyValuePropertyReplacer Members

    //Called by framework to see it is valid property replacer for the passed propertyName
    public bool ContainsProperty(string propertyName)
    {
        return _availPropeties.ContainsKey(propertyName);
    }

    //Yes it is, then framework calls this method to find the value for the property
    public string ReplaceProperty(string propertyName, string format)
    {
        switch (propertyName)
        {
            case "HOME_PAGE":
                return "http://www.cinchoo.com";
            case "LAST_VISIT":
                return ChoObject.Format(DateTime.Now, format);
            default:
                return null;
        }
    }

    //This method will be used to generate help
    public string GetPropertyDescription(string propertyName)
    {
        if (_availPropeties.ContainsKey(propertyName))
            return _availPropeties[propertyName];
        else
            return null;
    }

    #endregion

    #region IChoPropertyReplacer Members

    //Name of the property replacer
    public string Name
    {
        get { return "Dynamice Property Replacer"; }
    }

    //This property used to get list of supported properties and their descriptions
    public IEnumerable<KeyValuePair<string, string>> AvailablePropeties
    {
        get
        {
            foreach (KeyValuePair<string, string> keyValue in _availPropeties)
                yield return keyValue;
        }
    }

    #endregion
}

Here is the code to plug-in the above property replacer to the framework and using it.

static void Main(string[] args)
{
    ChoPropertyManagerSettings.Me.Add(new ChoDynamicPropertyReplacer());

    Console.WriteLine("Output of %%HOME_PAGE%% : %HOME_PAGE%".ExpandProperties());
    Console.WriteLine("Output of %%LAST_VISIT%% : %LAST_VISIT%".ExpandProperties());

    return;
}

When you run the above statements in an application, the output will be

Output of HOME_PAGE : http://www.cinchoo.com
Output of LAST_VISIT : 1/17/2012 1:07:23 PM

Hope this helps.