I have assembly X that consumes an app.config file with a custom section. <section> elements require a handler class and an assembly name. This all works fine when referencing assembly X from my main host app.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="Foo" type="Foo.Common.FooConfigurationSectionHandler, Foo.Common" />
</configSections>
<Foo xmlns="http://mycompany.com/foo/configuration">
<property name="Foo.Server.ConnectionString" value="zipzap" />
</Foo>
</configuration>
I now want to reference X via a C# script (csi.exe). I have the section handler assembly Foo.Common.dll in the script directory, I reference it in the script, and I'm able to use classes within that assembly, proving that csi.exe can successfully load the assembly Foo.Common.
#r "Foo.Common.dll"
using Foo.Common;
/**
code that successfully uses a class from Foo.Common here
**/
However, when I then try to then run code that loads the app.config, .NET's configuration manager fails to find the assembly Foo.Common:
#r "Foo.Common.dll"
using Foo.Common;
/**
code that successfully uses a class from Foo.Common
**/
/**
code that requires loading the App.Config file shown above
THIS FAILS, because the configuration manager can't find the type Foo.Common
**/
The error from System.Configuration:
An error occurred creating the configuration section handler for Foo: Could not load file or assembly 'Foo.Common' or one of its dependencies. The system cannot find the file specified. (C:\stuff\desk\script\App.config line 4)
at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
EDIT: I did some experimenting and found that if I put all the DLLs into the same folder as CSI.EXE, then this code works. The Configuration manager appears to be trying to resolve DLLs relative to the EXE location, rather than the current directory.
Unfortunately, this won't work for me, because in my full use case, there are DLL conflicts between my app and CSI.exe's assemblies, so I can't put them in the same folder.
The problem is that the configuration manager was trying to resolve assemblies relative to the EXE's location, rather than the current directory or the app.config directory.
I had already written the following to make it use the app.config in my script directory:
I ad to add the following to help it resolve assemblies referenced in that config file, relative to the current directory:
With that in place, resolving the assembly for my custom config
<section>worked.