C
Chris Finlayson
Hi:
There's quite a bit of interest out there in using config files with
..dll's. I've seen some implementations which boil down to figuring
out a file named "<something>.config.dll" and then using some manual
xml reader. I wanted to utilize the configSection of the app reader
whereby it defaults to the appropriate handlers as defined in the xml.
I did not want to rewrite that logic, so as an idea, I thought of
having a .dll redirect the call to another appdomain that's
dynamically created (so you can specify the configuration file).
With this approach, the .dll configuration loading is done in the same
way an app is loaded. I'd be curious to hear about what people think
of this approach. According to the documentation, creating appdomains
is pretty minimal overhead, both in speed and memory.
As a simple example, see the below three files:
1. the main program
2. MyDLL - a dll with a configuration file
3. MyDLL.config.dll - the config file to go with MyDLL, in a format
that adheres to the application configuration schema
/*************
The main program
****************/
using System;
using System.Reflection;
using System.Configuration;
using System.Security.Policy; //for evidence object
using System.Collections;
using System.Runtime.Remoting;
namespace App
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
AppDomain currentDomain = AppDomain.CurrentDomain;
//Create the application domain setup information.
AppDomainSetup domaininfo = new AppDomainSetup();
//I was just playing around with the below settings. Set up
AppDomainSetup
//however you see fit
domaininfo.ApplicationBase = currentDomain.BaseDirectory;
domaininfo.PrivateBinPath=currentDomain.BaseDirectory;
domaininfo.PrivateBinPathProbe=currentDomain.DynamicDirectory;
//Setting the config file is the most important
part. domaininfo.ConfigurationFile="C:\\junk\\ConfigTest\\App\\bin\\Debug\\MyDLL.dll.config";
//Create evidence for new appdomain.
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
// Create the new application domain using setup information.
AppDomain domain = AppDomain.CreateDomain("MyDomain", adevidence,
domaininfo);
ObjectHandle o = domain.CreateInstance("MyDLL","MyDLL.Class1");
MyDLL.Class1 oclass1 = (MyDLL.Class1)o.Unwrap();
oclass1.SomeProperty();
Assembly[] assems = currentDomain.GetAssemblies();
//List the assemblies in the current application domain.
Console.WriteLine("List of assemblies loaded in current
appdomain:");
foreach (Assembly assem in assems)
Console.WriteLine(assem.ToString());
Console.WriteLine("\n\nList of assemblies loaded in other
appdomain:");
Assembly[] assems2 = domain.GetAssemblies();
foreach (Assembly assem in assems2)
Console.WriteLine(assem.ToString());
AppDomain.Unload(domain);
}
}
}
/***********
MyDLL .dll
*****************/
using System;
using System.Configuration;
using System.Collections;
namespace MyDLL
{
/// <summary>
/// Summary description for Class1.
/// </summary>
///
public class Class1 : MarshalByRefObject
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
public void Tester()
{
System.Console.WriteLine("testing...");
}
public bool SomeProperty()
{
IDictionary oHandler =
(IDictionary)System.Configuration.ConfigurationSettings.GetConfig("dictionarySample");
bool ret=oHandler.Contains("mykey");
if (ret)
{
System.Console.WriteLine("true!");
}
return ret;
}
}
}
----------the "MyDLL.config.dll" file-------------------
<configuration>
<configSections>
<section name="dictionarySample"
type="System.Configuration.DictionarySectionHandler"/>
</configSections>
<dictionarySample>
<add key="myKey" value="myValue"/>
</dictionarySample>
</configuration>
There's quite a bit of interest out there in using config files with
..dll's. I've seen some implementations which boil down to figuring
out a file named "<something>.config.dll" and then using some manual
xml reader. I wanted to utilize the configSection of the app reader
whereby it defaults to the appropriate handlers as defined in the xml.
I did not want to rewrite that logic, so as an idea, I thought of
having a .dll redirect the call to another appdomain that's
dynamically created (so you can specify the configuration file).
With this approach, the .dll configuration loading is done in the same
way an app is loaded. I'd be curious to hear about what people think
of this approach. According to the documentation, creating appdomains
is pretty minimal overhead, both in speed and memory.
As a simple example, see the below three files:
1. the main program
2. MyDLL - a dll with a configuration file
3. MyDLL.config.dll - the config file to go with MyDLL, in a format
that adheres to the application configuration schema
/*************
The main program
****************/
using System;
using System.Reflection;
using System.Configuration;
using System.Security.Policy; //for evidence object
using System.Collections;
using System.Runtime.Remoting;
namespace App
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
AppDomain currentDomain = AppDomain.CurrentDomain;
//Create the application domain setup information.
AppDomainSetup domaininfo = new AppDomainSetup();
//I was just playing around with the below settings. Set up
AppDomainSetup
//however you see fit
domaininfo.ApplicationBase = currentDomain.BaseDirectory;
domaininfo.PrivateBinPath=currentDomain.BaseDirectory;
domaininfo.PrivateBinPathProbe=currentDomain.DynamicDirectory;
//Setting the config file is the most important
part. domaininfo.ConfigurationFile="C:\\junk\\ConfigTest\\App\\bin\\Debug\\MyDLL.dll.config";
//Create evidence for new appdomain.
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
// Create the new application domain using setup information.
AppDomain domain = AppDomain.CreateDomain("MyDomain", adevidence,
domaininfo);
ObjectHandle o = domain.CreateInstance("MyDLL","MyDLL.Class1");
MyDLL.Class1 oclass1 = (MyDLL.Class1)o.Unwrap();
oclass1.SomeProperty();
Assembly[] assems = currentDomain.GetAssemblies();
//List the assemblies in the current application domain.
Console.WriteLine("List of assemblies loaded in current
appdomain:");
foreach (Assembly assem in assems)
Console.WriteLine(assem.ToString());
Console.WriteLine("\n\nList of assemblies loaded in other
appdomain:");
Assembly[] assems2 = domain.GetAssemblies();
foreach (Assembly assem in assems2)
Console.WriteLine(assem.ToString());
AppDomain.Unload(domain);
}
}
}
/***********
MyDLL .dll
*****************/
using System;
using System.Configuration;
using System.Collections;
namespace MyDLL
{
/// <summary>
/// Summary description for Class1.
/// </summary>
///
public class Class1 : MarshalByRefObject
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
public void Tester()
{
System.Console.WriteLine("testing...");
}
public bool SomeProperty()
{
IDictionary oHandler =
(IDictionary)System.Configuration.ConfigurationSettings.GetConfig("dictionarySample");
bool ret=oHandler.Contains("mykey");
if (ret)
{
System.Console.WriteLine("true!");
}
return ret;
}
}
}
----------the "MyDLL.config.dll" file-------------------
<configuration>
<configSections>
<section name="dictionarySample"
type="System.Configuration.DictionarySectionHandler"/>
</configSections>
<dictionarySample>
<add key="myKey" value="myValue"/>
</dictionarySample>
</configuration>