CS-Script 3.27.0


CS-Script application configuration

Background

Application Settings vs. Script Application Settings

One of the possible ways of maintaining an application settings is a Configuration File. This is how MSDN describes the configuration files:

The .NET Framework gives developers control and flexibility over the way applications run. Developers can put settings in configuration files, eliminating the need to recompile an application every time a setting changes. Application configuration files contain settings specific to an application. 

Configuration files are XML files that can be changed as needed.

Typically the application configuration file is in the same directory as the application. The name of the configuration file is the name of the application with a .config extension (app.config). For example, an application called myApp.exe can be associated with a configuration file called myApp.exe.config.

Unfortunately such configuration file cannot be used to store the script application settings. This is because all the scripts share the same executable and in result they have to share the same app.config. The solution to the problem is to use different config file, associated with the script but not with the application executable (script.config). For example, a script called myScript.cs has to be associated with a configuration file called myScript.cs.config.


Custom config file
.NET Framework provides classes for working with configuration files. One of them is System.Configuration.ConfigurationSettings.AppSettings, which makes reading the app.config file effortless. Unfortunately this class cannot be used for script.config as there is no simple/adequate way to force it to read anything else but app.config

There are plenty of articles/code samples dedicated to solving the custom config file problem.  Approaches are different and usually they are based on the custom config file reader.  The same approach is used for CS-Script. However one of the simplest and most reliable approaches is to access configuration file from some temporary domain (TempDomain approach). In this case you can use all existing .NET classes for working with configuration files.  The approach is based on the fact that you can specify what config file temporary domain should use. The advantages of such approach are obvious:
The example of such approach is the following script: Tutorial/AppSettings/CustomAppSettings.cs.

However there is always a catch. Crossing the domain boundaries introduces some performance penalties (which are in real life often negligible).

Script AppConfig file support

The described above algorithm is used for implementation of the support for app.config file associated with the script application?

Starting from version  1.7.0 CS-Script supports true application configuration files. Practically it means that if you need to execute the script (client.cs) written to access a configuration file, you need to create corresponding config file (client.cs.config) and use command-line switch
/sconfig. This switch will force the script engine to execute the script application in a separate AppDomain with client.cs.config or  as a config file.

Note that /sconfig is a default option for the script execution. Also be aware that the script engine will treat client.exe.config (if found) as a script config file in absence of client.cs.config.

Also you can specify custom name for the config file by using extended syntax for /sconfig command-line argument: /sconfig:MyApp.config.

See <cs-script>\Samples\ConfigFiles samples

The way of accessing the app.config file values from script, when /sconfig option is used, is not different from accessing these values from the stand alone application.

using System;
using System.Windows.Forms;
using System.Configuration;

class Script
{
    static public void Main(string[] args)
    {
        MessageBox.Show(ConfigurationManager.AppSettings["greeting"]);
    }
}

....

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="greeting" value="Hello!" />
    </appSettings>
</configuration


The AppCconfig support is especially important with respect to the WPF and WCF applications, which relay heavily on the app.config files. For such script applications /sconfig is a "must-have" option.

Another interesting aspect of AppConfig support is the concept of assembly aliases for configuration file ConfigSections. Assembly aliases mechanism is required for resolving problems caused by unpredictable nature of the assembly name of the compiled script. The following example will illustrate how to use assembly aliases in practice.

Imagine that you have application MyApp.exe which uses MyApp.exe.config configuration file. The following XML is a fragment of the configSection of the MyApp.exe.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="MyData" type="MyDataSection, MyApp" 

As you can see from the code above section MyData is bound to the MyDataSection type implemented in the MyApp assembly.

But what if you want to achieve the same in a script application. Let's assume that  MyDataSection type is implemented in the script MyApp.cs. However it is not possible to specify the assembly name in the app.config file as we do not have our assembly yet, we have only script. Well the problem can be handled quite easy. XML configuration file (MyApp.cs.config) should contain assembly alias GetExecutingAssembly().

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="MyData" type="MyDataSection, GetExecutingAssembly()"

GetExecutingAssembly() is interpreted at runtime as an executing assembly (loaded script). Thus the only difference between executable and the script application is the assembly name field in the config file.

Similarly GetEntryAssembly() is mapped to the process executable assembly.

The actual working with the config file sections from the script is not that different comparing to the same scenario implemented in the stand alone application. The only diffrence is usage of GetExecutingAssembly() instead of the assembly name.
The full scale example for working with AppConfig sections is the following script: Tutorial/AppSettings/AppConfigSection.cs.

See Also 

Command-line_Interface