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:
- Simplicity: the only extra code you need to do is the creation of a new AppDomain.
- Consistency: actual configuration accessing routine is the same as for standard app.config.
- Reliability: app.config readers/writers are part of the .NET Framework, well tested and maintained by MS.
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).
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 A
ppCconfig 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