アセンブリをオンデマンドでGACにインストールし(ボタンをクリックすると)、アセンブリを試行するアプリケーションで作業しているときに、どういうわけか問題が発生しました。次のボタンをクリックしてロードするか、からメソッドを呼び出そうとします。その新しくGACされたアセンブリですが、失敗します。問題と再現の手順は以下のとおりです。
問題と再現の手順: 次の名前のFooGreet.dllのような新しいクラスライブラリを作成し、厳密な名前を付けます。後でアセンブリフォルダにドラッグしましょう。
namespace FooGreet
{
public class Greeting
{
public string SayHello()
{
return "Hello";
}
}
}
次のコードのように、上記のクラスライブラリをロードするコンソールアプリケーションを作成します。
namespace FooGreetCaller
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press Enter to load assembly..");
while (true)
{
string input = Console.ReadLine();
if (input == "q" || input == "Q")
break;
try
{
System.Reflection.Assembly.Load("FooGreet, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=3f330bcf59df56c9");
Console.WriteLine("Assembly load success.");
}
catch (Exception eX)
{
Console.WriteLine(eX.Message + Environment.NewLine + eX.StackTrace);
}
}
}
}
}
- コンソールアプリケーションを実行します。コンソールアプリケーションのインスタンスを実行します。FooGreet.dllをロードしようとすると、何度ロードしても「ファイルまたはアセンブリをロードできませんでした…。」という例外が発生します。コンソールウィンドウを閉じないでください。
- FooGreet.dllをGACにインストールします。FooGreet.dllをGACにドラッグします。コンソールアプリケーションの同じインスタンスで、FooGreet.dllを再度ロードしようとすると、同じ例外が発生します。FooGreet.dllがGACにあり、コンソールアプリケーションがそれを認識しているはずなので、これを異常と呼びます。持ってはいけませんか?
- コンソールアプリケーションの2番目のインスタンスを実行します。コンソールアプリケーションの2番目のインスタンスを実行します。FooGreet.dllをロードしてみてください。これで、アセンブリが正常にロードされます。
- GACからFooGreet.dllをアンインストールします。GACに移動し、FooGreet.dllをアンインストールします。コンソールアプリケーションの2番目のインスタンスでFooGreet.dllを再度ロードしてみてください。アセンブリが正常にロードされました。理想的には、「ファイルまたはアセンブリをロードできませんでした…」のような例外をスローするべきではありませんか?
質問: 質問はステップ2と4にあります。ステップ2とステップ4での出来事から、アプリケーションが読み込まれると、GACのスナップショットが作成されるように見えます(少なくともデフォルトのAppDomainでは、作成を試みていません)新しいAppDomainをロードします)。これは本当ですか?
(私のアプリでは、回避策として、特定のアセンブリをGACに登録した後にアプリケーションを再起動します。
System.EnterpriseServices.Internal.Publish().GacInstall(targetAssemblyName);
私はWinFormsアプリを使用していて、Form_Loadで再起動を行っています。これにより、メインフォームがほんの一瞬点滅します。これは気に入らないです)