これは奇妙な質問のように聞こえるかもしれません (少なくとも、私は今までそれについて考える理由がありませんでした)、私の状況を説明させてください。
クライアントのネットワーク上のサーバーで実行されるサービス アプリがあります。アプリを更新するには、サービスのコア アセンブリの新しいビルドをサーバーにプッシュし、サービス アプリにソフト リスタートを発行します。これは実際にはコアの単なるシェルです。個々のサービス アプリがコア アセンブリのバイト配列を要求し、新しいアセンブリが実行されます。
Assembly coreAsm = Assembly.Load(coreAsmByteArray);
Type tCoreHelper = GetInterfaceTypeFromAssembly(coreAsm, typeof(ICoreHelper));
_CoreHelper = Activator.CreateInstance(tCoreHelper) as ICoreHelper;
_CoreHelper.Start();
サービスの実行に必要なものはすべて、最近までコア アセンブリに含まれていました。
サービス アプリからプラグイン アセンブリを要求できるように、いくつかの変更を加えました。サービスが最初に実行されると、コア アセンブリが要求され、コアはプラグインを要求し、コアと同じ方法でそれらをロードします (異なる正しい型が想定されます)。アセンブリがリロードされ、すべてが満足しています。ただし、ソフト リスタートを発行すると、コア アセンブリが要求され、コア アセンブリがプラグインを要求します。コア アセンブリとプラグイン アセンブリは正常に読み込まれますが、プラグインとコアの型の間の型チェックが失敗し始めます。
プラグイン アセンブリをロードした後、コア アセンブリで定義された型であるワーカー クラス IWorker を探すプラグインの型を調べます (すべてのプラグイン アセンブリがコアを参照することを意味します)。
アセンブリ コア:
namespace Core
{
public interface IWorker { ... }
}
アセンブリ PluginTest:
namespace PluginTest
{
public class PluginA : Core.IWorker { ... }
}
(new)Core.IWorker はプラグイン ワーカー タイプから割り当てられなくなったため、サービス アプリの初期ロードで以前に見つかったすべてのワーカーは、ソフト リスタート後に見つからなくなりました。デバッガーは同意せず、希望する方法で IsAssignableFrom への呼び出しを評価しますが、CLR は別のことを行っているため、チェックが失敗します。
foreach(var t in pluginAsm.GetTypes())
{
if(otherChecksPass && typeof(IWorker).IsAssignableFrom(t))
RegisterPluginType(t);
}
プラグインの下からコア アセンブリを変更すると、プラグインは新しいコア アセンブリに関するメモを取得せず、古いアセンブリへの「キャッシュされた」参照を引き続き使用していると思います。しかし、この種の状況が記憶の中でどのように展開するかは本当にわかりませんし、そのような状態を修正する方法についてもまったくわかりません.
質問?考え?皆さん、ありがとうございました!