Cinchoo – Configuration framework, part 27

Using Converters

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

Cinchoo configuration framework takes care of converting most of the intrinsic type configuration object members from text value like string to int, string to enum etc. In cases where you have custom type members, you will have to use converters to convert the text value to object. Cinchoo support the following types of converters

  1. System.ComponentModel.TypeConverter – For more information about it, visit ‘How to: Implement a TypeConverter
  2. System.Windows.Data.IValueConverter
  3. Cinchoo.Core.IChoValueConverter – It is similar interface to IValueConverter.

TypeConverters can be specified two ways using ChoTypeConverterAttribute 

  1. At each object member level – Will take priority over second option
  2. At the object type level

Lets go over with sample configuration object defined below

[ChoNameValueConfigurationSection("appSettings")]
public class AppSettings : ChoConfigurableObject
{
    [ChoPropertyInfo("name", DefaultValue = "Raj")]
    public string Name;

    [ChoPropertyInfo("address", DefaultValue = "21, Melbloum Lane, Edison NJ 08837")]
    public string Address;

    [ChoPropertyInfo("Color", DefaultValue = "Yellow")]
    public ConsoleColor Color;

    [ChoPropertyInfo("height", DefaultValue = "5.6")]
    public double Height;

    [ChoPropertyInfo("SSN", DefaultValue = "111-00-3333")]
    [ChoTypeConverter(typeof(SSNConverter))]
    public string SSN;

    [ChoPropertyInfo("Location", DefaultValue = "10, 12")]
    public Point Location;

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

In here,

  • Color is of ConsoleColor enum type. As I mentioned earlier, it is implicitly taken care by Cinchoo framework to read/store the value as string.
  • SSN is of string type, expects values in specific format (000-00-0000). It is decorated with member level type converter ‘SSNConverter’
  • Location is of Point type. But Point class bounded to PointConverter as below. No need to specify at the member level.

SSNConverter Implementation

public class SSNConverter : TypeConverter
{
    private static readonly Regex _ssnRegex = new Regex(@"^[0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9][0-9][0-9]$|^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$", RegexOptions.Compiled);
    private static readonly Regex _noSSNRegex = new Regex(@"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$", RegexOptions.Compiled);
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string);
    }
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value != null && value is string)
        {
            string ssnValue = value as string;
            if (_ssnRegex.IsMatch(ssnValue))
                return ssnValue;
            else if (_noSSNRegex.IsMatch(ssnValue))
                return "{0}-{1}-{2}".FormatString(ssnValue.Substring(0, 2), ssnValue.Substring(2, 4), ssnValue.Substring(4, 7));
        }
        throw new ArgumentException("Invalid '{0}' SSN value passed.".FormatString(value));
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string);
    }
    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        return (string)value;
    }
}

PointConverter Implementation

[ChoTypeConverter(typeof(Point))]
public class PointConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value is string)
        {
            if (targetType == typeof(Point))
            {
                int x = 0, y = 0;
                string inValue = value as string;
                string[] parts = inValue.SplitNTrim(',');
                if (parts.Length >= 1)
                    x = System.Convert.ToInt32(parts[0]);
                if (parts.Length >= 2)
                    y = System.Convert.ToInt32(parts[1]);
                return new Point(x, y);
            }
        }
        return value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value is Point)
        {
            if (targetType == typeof(string))
            {
                Point inValue = (Point)value;
                return "{0}, {1}".FormatString(inValue.X, inValue.Y);
            }
        }

        return value;
    }
}

You can use any existing TypeConverter / IValueConverter in your application. Try for yourself. Thanks.


Cinchoo – Configuration framework, part 26

Using ChoFireBirdADODictionaryConfigStorage

UPDATE:

This article is outdated. Please visit the below codeproject article for more updated information on this storage plug-ins

Cinchoo – Using FireBird database as configuration source

Using FireBird database as configuration store using Cinchoo framework made easy with this storage plug-in. Using ChoFireBirdADODictionaryConfigStorage, you can read and store application configuration information easily. It is based on ChoDictionaryAdapterConfigurationSection pattern and uses ADO.NET as the database access medium. You can take this one as an example and implement various plug-ins targeting various other databases. Here is how you can use this storage

  • Download and install FireBird Db from here.
  • Create a table using the below Sql. I designed this table in such a way you can use them for multiple applications. Thats why I set the ‘AppName’ as primary key.
CREATE TABLE application_settings
(
 Path varchar(255) DEFAULT NULL,
 OS varchar(50) DEFAULT NULL,
 SingleInstanceApp int DEFAULT NULL,
 LastUpdateTimeStamp timestamp NOT NULL,
 AppName varchar(255) NOT NULL,
 PRIMARY KEY (AppName)
);
  • Create a VS project and add reference to ChoFireBirdADODictionaryConfigStorage.dll
  • Define the configuration section object decorated with ChoDictionaryAdapterConfigurationSectionAttribute as below.
[ChoDictionaryAdapterConfigurationSection("fireBirdDictionarySectionHandlerTest/applicationSettings",
    typeof(ChoFireBirdADODictionaryConfigObjectAdapter),
    "CONNECTION_STRING='User=SYSDBA;Password=masterkey;Database=C:\Users\raj\AppData\Local\Temp\Sample.fdb;DataSource=localhost';
    TABLE_NAME=APPLICATION_SETTINGS;LAST_UPDATE_DATETIME_COLUMN_NAME=LastUpdateTimeStamp;KEY_COLUMN_NAME=AppName")]
public class ApplicationSettings : ChoConfigurableObject
{
    [ChoPropertyInfo("path", DefaultValue = "C:\")]
    public string Path;

    [ChoPropertyInfo("OS", DefaultValue = "Windows")]
    public string OS;

    [ChoPropertyInfo("singleInstanceApp", DefaultValue = false)]
    public bool SingleInstanceApp;
}

2. Now instantiate and use it as below

static void Main(string[] args)
{
    ApplicationSettings applicationSettings = new ApplicationSettings();

    ChoConsole.Pause();

    applicationSettings.OS = "Microsoft";

    ChoConsole.Pause();
}

The configuration section will be generated automatically for the first time in [appExeName].xml as below

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="fireBirdDictionarySectionHandlerTest">
      <section name="applicationSettings" type="Cinchoo.Core.Configuration.ChoDictionarySectionHandler, Cinchoo.Core, Version=1.0.1.1, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de" />
    </sectionGroup>
  </configSections>
  <fireBirdDictionarySectionHandlerTest>
    <applicationSettings cinchoo:configObjectAdapterType="Cinchoo.Core.Configuration.ChoFireBirdADODictionaryConfigObjectAdapter, ChoFireBirdADODictionarySectionHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework">
      <cinchoo:configObjectAdapterParams xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework"><![CDATA[CONNECTION_STRING='User=SYSDBA;Password=masterkey;Database=C:\Users\raj\AppData\Local\Temp\Sample.fdb;DataSource=localhost';
        TABLE_NAME=APPLICATION_SETTINGS;LAST_UPDATE_DATETIME_COLUMN_NAME=LastUpdateTimeStamp;KEY_COLUMN_NAME=AppName]]></cinchoo:configObjectAdapterParams>
    </applicationSettings>
  </fireBirdDictionarySectionHandlerTest>
</configuration>

Cinchoo – Configuration framework, part 25

Using ChoMySqlADODictionaryConfigStorage

UPDATE:

This article is outdated. Please visit the below codeproject article for more updated information on this storage plug-ins

Cinchoo – Using MySql database as configuration source

Using MySql database as configuration store using Cinchoo framework made easy with this storage plug-in. Using ChoMySqlADODictionaryConfigStorage, you can read and store application configuration information easily. It is based on ChoDictionaryAdapterConfigurationSection pattern and uses ADO.NET as the database access medium. You can take this one as an example and implement various plug-ins targeting various other databases. Here is how you can use this storage

  • Download and install MySql from here.
  • Create a table using the below Sql. I designed this table in such a way you can use them for multiple applications. Thats why I set the ‘AppName’ as primary key.

CREATE TABLE `application_settings` (
 `Path` varchar(255) DEFAULT NULL,
 `OS` varchar(50) DEFAULT NULL,
 `SingleInstanceApp` bit(1) DEFAULT NULL,
 `LastUpdateTimeStamp` datetime NOT NULL,
 `AppName` varchar(255) NOT NULL,
 PRIMARY KEY (`AppName`)
)

  • Create a VS project and add reference to ChoMySqlADODictionaryConfigStorage.dll
  • Define the configuration section object decorated with ChoDictionaryAdapterConfigurationSectionAttribute as below.
[ChoDictionaryAdapterConfigurationSection("mySqlDictionarySectionHandlerTest/applicationSettings",
    typeof(ChoMySqlADODictionaryConfigObjectAdapter),
    @"CONNECTION_STRING='server=localhost;User Id=root;password=admin;Persist Security Info=True;database=test';
    TABLE_NAME=APPLICATION_SETTINGS;LAST_UPDATE_DATETIME_COLUMN_NAME=LastUpdateTimeStamp;KEY_COLUMN_NAME=AppName")]
public class ApplicationSettings : ChoConfigurableObject
{
    [ChoPropertyInfo("path", DefaultValue = @"C:\")]
    public string Path;

    [ChoPropertyInfo("OS", DefaultValue = "Windows")]
    public string OS;

    [ChoPropertyInfo("singleInstanceApp", DefaultValue = false)]
    public bool SingleInstanceApp;
}

2. Now instantiate and use it as below

static void Main(string[] args)
{
    ApplicationSettings applicationSettings = new ApplicationSettings();

    ChoConsole.Pause();

    applicationSettings.OS = "Microsoft";

    ChoConsole.Pause();
}

The configuration section will be generated automatically for the first time in [appExeName].xml as below

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="mySqlDictionarySectionHandlerTest">
      <section name="applicationSettings" type="Cinchoo.Core.Configuration.ChoDictionarySectionHandler, Cinchoo.Core, Version=1.0.1.1, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de" />
    </sectionGroup>
  </configSections>
  <mySqlDictionarySectionHandlerTest>
    <applicationSettings cinchoo:configObjectAdapterType="Cinchoo.Core.Configuration.ChoMySqlADODictionaryConfigObjectAdapter, ChoMySqlADODictionaryConfigStorage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework">
      <cinchoo:configObjectAdapterParams xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework"><![CDATA[CONNECTION_STRING='server=localhost;User Id=root;password=admin;Persist Security Info=True;database=test';
        TABLE_NAME=APPLICATION_SETTINGS;LAST_UPDATE_DATETIME_COLUMN_NAME=LastUpdateTimeStamp;KEY_COLUMN_NAME=AppName]]></cinchoo:configObjectAdapterParams>
    </applicationSettings>
  </mySqlDictionarySectionHandlerTest>
</configuration>

Cinchoo – Bulk Files & Folders rename utility

ChoBulkFileRenameTool

Download Binary (Zip)

Download Source (Zip)

This tool helps to rename bulk files and folders recursively. It was written in using WPF/C#/VS.NET 2010.

Features

  • Bulk file and folders rename matching either wildcard or regular expression patterns
  • Runs on Windows 95/98/ME/NT4/2k/2k3/2k8/XP/Vista/7

How to use

  • Click ‘Start’ whenever you are ready to rename files. Any time you can can start this process.
  • Type a full path of the file or folder in ‘Choose a File / Folder’ text box, then click ‘Add’ button to add it to ‘File(s) / Folder(s)’ list box. Or you can click ‘Browse’ button, to choose the file/folder for rename.
  • At any time, you can select an item in ‘File(s) / Folder(s)’ list box, remove it using ‘Remove’ button.
  • In ‘Find/Replace’ text boxes, you can specify either the wildcard or regular expression to identify files and folders for rename. (Please visit Regular Expression Cheat Sheet for help in creating regular expression)
  • Check ‘Match Files’ or ‘Match Folders’ check boxes, in order to include them for rename process respectively.
  • Check ‘Preview Mode’ option, if you just want to see the files and folders are renamed in the ‘Status’ box or in the log file under ‘Logs’ folder. This option will not rename the files or folder names.
  • Check ‘Include Sub Dir’ option, to include all sub directories for rename process.
  • In ‘Status’ box, you can view the statues of the file renames.
  • Click ‘Clear’ button anytime to clear the ‘Status’ box.

Tips

  • You can drag and drop file(s) or folder(s) to this tool for easy cleanup process.

Cinchoo – Hierarchical INI sections, Part 9

In this section, I’ll talk about another important feature Cinchoo framework provides in reading INI file is that the support of  Hierarchical INI sections. It gives the flexibility of organizing the INI sections in hierarchical way. An INI section can have another INI subsection in it. Here is how you can do it using Cinchoo framework,

;This is a test nested INI file.
;To test its functionality.

[CORPORATIONS]

[CORPORATIONS/FINANCE]
CORP1=JP Morgan Chase
COPR2=Morgan Stantley

[CORPORATIONS/TECHNOLOGY]
CORP1=Google
COPR2=Apple

In the above sample INI file, the Hierarchical sections are given with ‘/’ separator. ‘CORPORATIONS’ section contains ‘FINANCE’ and ‘TECHNOLOGY’ subsections. There are couple ways, we can access them programmatically

using (ChoIniDocument iniDocument = ChoIniDocument.Load(@"C:\Temp\NestedIniSection.ini"))
{
    Console.WriteLine(iniDocument["CORPORATIONS/TECHNOLOGY"]["CORP1"]);
    Console.WriteLine(iniDocument["CORPORATIONS"].GetSection("TECHNOLOGY")["CORP1"]);
}

Cinchoo – Turn your app to Windows Tray app

In this article, I’ll show you how to turn your console / winform application to Windows System Tray application. Cinchoo framework provides a single hosting infrastructure to turn your application either Windows Service or Windows Tray application through configuration.

Console Application

Here is how you can do it for console application

1. Create a new ‘Console Application‘ from VS.NET

2. Add reference to Cinchoo.Core.dll

3. Add namespace Cinchoo.Core

4. Create a class derived from ChoApplicationHost as below

[RunInstaller(true)]
public class AppHost : ChoApplicationHost
{
    protected override void OnStart(string[] args)
    {
        //TODO: Application Startup code goes here
        base.OnStart(args);
    }
}

Decorating the above class with RunInstallerAttribute will make the application to be run as Windows Service. And override OnStart method, where application start up code placed there.

5. In the main entry, do as below.

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run(new AppHost(), args);
    }
}

That’s all, you application is now ready to run as self installable windows service application or Windows Tray application.

Here is how to turn your application to Windows Tray application. In ChoCoreFrx.xml file, set ‘turnOn’ flag to ‘true’ in trayApplicationBehaviourSettings element.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <globalApplicationSettings applicationId="TestApplication.exe" eventLogSourceName="TestApplication.exe" turnOnConsoleOutput="false">
    <behaviourSettings hideWindow="false" bringWindowToTop="false" alwaysOnTop="false" runAtStartup="false" runOnceAtStartup="false" singleInstanceApp="false" activateFirstInstance="false" />
    <trayApplicationBehaviourSettings turnOn="true" showInTaskbar="true" hideMainWindowAtStartup="true" hideTrayIconWhenMainWindowShown="false" trayAppTurnOnMode="OnMinimize" />
    <appConfigPath />
  </globalApplicationSettings>
</configuration>

Other parameters

  • showInTaskbar – true, will show the application in Taskbar. false, otherwise.
  • hideMainWindowAtStartup – true, will hide the window at the application startup. Otherwise false.
  • hideTrayIconWhenMainWindowShown – true, tray application icon will hidden when the main windows shown. Otherwise false.
  • trayAppTurnOnMode – This option is applicable to WinForm application only. Possible options are OnMinimize, OnClose, OnMinimizeOrClose.

WinForm Application

Below are the steps to turn your winform application into Windows Tray application

1. Create a new ‘WinForm Application‘ from VS.NET

2. Add reference to Cinchoo.Core.dll

3. Add namespace Cinchoo.Core

4. Create a class derived from ChoApplicationHost and IChoWinFormApp as below

[RunInstaller(true)]
public class AppHost : ChoApplicationHost, IChoWinFormApp
{
    MainForm form = new MainForm();
    public AppHost()
    {
    }

    public Form MainFormWindow
    {
        get { return form; }
    }

    public ContextMenu GetContextMenu(ContextMenu contextMenu)
    {
        //Build the context menu items
        return contextMenu;
    }

    public string TooltipText
    {
        get { return null; }
    }

    public System.Drawing.Icon TrayIcon
    {
        get { return null; }
    }

    public string BalloonTipText
    {
        get { return null; }
    }

    protected override void OnStart(string[] args)
    {
        base.OnStart(args);
    }
}

Decorating the above class with RunInstallerAttribute will make the application to be run as Windows Service. And override OnStart method, where application start up code placed there.

5. In the main entry, do as below.

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run(new AppHost(), args);
    }
}

Thats all. Try it.


Cinchoo – Application Host, Part 2

ChoApplicationHost

Using Cinchoo framework, you can set your application to run at windows start-up easily. Here is how you can do it

1. Add reference to Cinchoo.Core.dll

2. Add namespace Cinchoo.Core

[RunInstaller(true)] //Optional attribute, to host your application as Windows Service
public class AppHost : ChoApplicationHost
{
    protected override void OnStart(string[] args)
    {
        //TODO: Application Startup code goes here
    }
}

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run<AppHost>(args);
    }
}

Open the Global Application Settings section in ChoCoreFrx.xml file (you can find it in application binary directory), set runAtStartup to true.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <globalApplicationSettings applicationId="TestApplication.exe" eventLogSourceName="TestApplication.exe" turnOnConsoleOutput="false">
    <behaviourSettings hideWindow="false" bringWindowToTop="false" alwaysOnTop="false" runAtStartup="false" runOnceAtStartup="false" singleInstanceApp="false" activateFirstInstance="false" />
    <trayApplicationBehaviourSettings turnOn="true" showInTaskbar="true" hideMainWindowAtStartup="true" hideTrayIconWhenMainWindowShown="false" trayAppTurnOnMode="OnMinimize" />
    <logSettings traceLevel="4">
      <logFolder />
      <logFilename>TestApplication.exe</logFilename>
      <logTimeStampFormat>yyyy-MM-dd hh:mm:ss.fffffff</logTimeStampFormat>
    </logSettings>
    <appConfigPath />
  </globalApplicationSettings>
</configuration>

Override programmatically

Some scenarios you may want to control it programmatically. When it arises, you can do so as below

Method 1:

Subscribe to ApplyFrxParamOverrides eventhandler before ChoApplication.Run() as below.

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.ApplyFrxParamsOverrides += new EventHandler<ChoFrxParamsEventArgs>(ChoApplication_ApplyFrxParamsOverrides);
        ChoApplication.Run<AppHost>(args);
    }
    static void ChoApplication_ApplyFrxParamsOverrides(object sender, ChoFrxParamsEventArgs e)
    {
        e.GlobalApplicationSettings.ApplicationBehaviourSettings.RunAtStartup= true;
    }
}

Method 2:

You can override ApplyFrxParamsOverrides method in your AppHost class as below.

[RunInstaller(true)]
public class AppHost : ChoApplicationHost
{
    protected override void OnStart(string[] args)
    {
    }

    protected override void ApplyFrxParamsOverrides(ChoGlobalApplicationSettings globalApplicationSettings, ChoMetaDataFilePathSettings metaDataFilePathSettings)
    {
        globalApplicationSettings.ApplicationBehaviourSettings.RunAtStartup = true;
    }
}
public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run<AppHost>(args);
    }
}

Follow

Get every new post delivered to your Inbox.