他のAppDomainからロードされたアセンブリの設定ファイルにアクセスする

<メモ>

通常の実行アセンブリの場合、デフォルトの設定ファイル(App.config)は実行アセンブリがロード、実行されたカレントのディレクトリの直下の

"アセンブリ表示名" + 拡張子(.exe) + ".config"

というパス名が使用される。これは決め事なので、アプリケーションや他のライブラリィが、下記のように書かれている設定ファイルの独自のセクション(fooSection)にアクセスする場合、適切なセクションハンドラ(Config.FooConfigHandler)クラスが用意されていれば


   
        
〜独自の要素を記述〜

以下のコードを書くだけで独自のセクションにアクセスできる。

Config.FooConfigHandler handler = ConfigurationManager.GetSection("fooSection") as Config.FooConfigHandler;

と、ここまでは普通だが、実行アセンブリが他のアプリケーションドメインからロードされた場合はこの「決め事」は通用しない。
元のAppDomainから生成された他のAppDomainがロードして実行したアセンブリの場合、設定ファイルのパスは不定(※)なので、ConfugurationManagerは最初に書いたデフォルトの設定ファイルのパスでは独自の設定ファイルを取得できないのだ。

※不定と書いたが、この時の設定ファイルへのパスがどこを指しているのかは検証していない。恐らくは元のAppDomainからロード、実行されたアセンブリのベースディレクトリのままなのではないか。

解決策としては、AppDomainを生成する際のセットアップオブジェクトである、AppDomainSetupクラスのConfigurationFileプロパティに適切なパスをセットする事だ。

例:

AppDomainSetup setup = new AppDomainSetup();
〜
setup.ApplicationBase = System.Environment.CurrentDirectory
setup.ConfigurationFile = System.Environment.CurrentDirectory + "\\" + assemblyFileName + ".exe.config";
〜
setup.LoaderOptimization = LoaderOptimization.MultiDomainHost;
//エビデンスは現在のドメインのものをベースに使う
System.Security.Policy.Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
System.Security.Policy.Evidence evidence = new System.Security.Policy.Evidence(baseEvidence);
AppDomain newAppDomain = AppDomain.CreateDomain("ドメインを識別する名前", evidence, setup);
〜

このようにして生成されたAppDomainは、通常と同じ決め事で、実行アセンブリのデフォルトの設定ファイルにアクセスできるようになる。むろん、ASP.NETのような"Web.config"等の固定のファィル名が配置されていることを、期待するような作りにもできる。