2007年04月16日

Enterprise Library Configuration Tool の TypeSelectorEditor(2)

  
前回の続きです。
今日の話題の中心は、AppDomain.AssemblyResolve イベントです。

TypeSelector.cs には、以下のようなコードがあります。

 private static Type[] LoadTypesFromAssembly(Assembly assembly) {
Type[] types = null;
try {
types = assembly.GetTypes();
} catch (ReflectionTypeLoadException) {
}
return types;
}


ここで、依存したアセンブリを読み込めないため、ReflectionTypeLoadException 例外が発生し、nullが返り、エラーメッセージが表示されてしまいます。
なお、引数で渡ってくる Assemblyは、Assembly.LoadFrom メソッドで、読み込まれた別フィルダにあるアセンブリのインスタンスです。

結局、TypeSelector.cs のTypeSelectorクラスに、以下のようなコードを追加して、対応しました。

  private static AppDomain currentDomain = AppDomain.CurrentDomain;

static TypeSelector() {
currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveEventHandler);
}

private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args) {
Assembly myAssembly;
string tempAssmbPath = "";

string path = System.Environment.GetEnvironmentVariable(
"EntLibAsmPath", EnvironmentVariableTarget.Process);
foreach (string assemblyFolder in path.Split(';')) {
tempAssmbPath = System.IO.Path.Combine(assemblyFolder,
args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
if (File.Exists(tempAssmbPath)) {
myAssembly = Assembly.LoadFrom(tempAssmbPath);
if (myAssembly != null) {
return myAssembly;
}
}
}
return null;
}


AppDomain.AssemblyResolve イベントはアセンブリの解決に失敗したときに発生します。
このイベントハンドラの引数の ResolveEventArgs.name プロパティには、解決するアセンブリ表示名が渡ってきますので、その情報を基に、アセンブリをロードするようにします。

これで、別ディレクトリにあるアセンブリを読み込むことが可能となります。

※このコードでは、環境変数に設定されているパスを検索しています。


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/50750455