サービスがバックグラウンドで継続的に実行され、実行時にプラグイン DLL を追加/削除できるソリューションを開発しています。このサービスは、必要に応じて必要なプラグインをロードし、実行してアンロードします。これはアンロード部分であり、現在私に問題を引き起こしています: 特定のクラスが初めて正常にロードされると (変数 tc)、DLL ファイルが更新されても再ロードされません。クラス/アセンブリ/アプリケーションドメインを適切にアンロードしていないと思うので、この最後のマイルを歩くためのアドバイスをいただければ幸いです。
編集:コードの最近の変更を反映するように投稿を更新し、アンロードが正確に影響を与えない場合を説明します: Linux Ubuntu (Mono 経由) では問題は発生しませんが、Windows 2008 Server では問題が発生します。特定のプラグイン DLL を新しいファイル バージョンに置き換えます。.NET フレームワークがアセンブリをどこかにキャッシュしているようで、再ロードせずに満足しています。DLL ファイル名は変更されませんが、File Version プロパティは異なるため、ランタイムが以前に読み込まれた DLL バージョンと読み込まれているバージョンを比較し、バージョン番号が異なる場合は新しいバージョンを使用することを期待します。別の名前の DLL ファイルからアセンブリをロードするようにコードを少し変更すると、期待どおりに再ロードが行われます。
using System;
using System.Reflection;
namespace TestMonoConsole
{
public interface ITestClass
{
void Talk();
}
class MainClass
{
public static void Main (string[] args)
{
string pluginPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string classAssembly = "TestClass";
string className = "TestMonoConsole.TestClass";
string command = "";
do
{
try
{
System.AppDomain domain = System.AppDomain.CreateDomain(classAssembly);
string pluginAssemblyFile = pluginPath + "/" + classAssembly + ".dll";
System.IO.StreamReader reader = new System.IO.StreamReader(pluginAssemblyFile, System.Text.Encoding.GetEncoding(1252), false);
byte[] b = new byte[reader.BaseStream.Length];
reader.BaseStream.Read(b, 0, System.Convert.ToInt32(reader.BaseStream.Length));
domain.Load(b);
reader.Close();
ITestClass tc = (ITestClass) Activator.CreateInstance(domain, classAssembly, className).Unwrap();
tc.Talk();
System.AppDomain.Unload(domain);
}
catch (System.IO.FileNotFoundException e)
{
Console.WriteLine (String.Format("Error loading plugin: assembly {0} not found", classAssembly));
}
command = Console.ReadLine();
} while (command == "");
}
}
}