私は、ユーザーがDLLを動的にロードおよびアンロードできるホットスワップ可能なプラグインシステムを構築しようとしています。できるだけコアアプリケーションを再起動する必要はありません。そのため、私は多くの機能を外部ライブラリに移行しています。私が調べた研究から、2番目のAppDomainを作成してDLLをロードし、それを実行するためのパラメータなどを渡す必要があります。現在、ほとんどのプログラムが動作していると思いますが、CreateInstanceのオブジェクトに対してAppDomain.Unwrap()関数を呼び出すとエラーが発生します。次のようにエラーがある:ここC#AppDomainがDLLを読み込めません
System.InvalidCastException: Unable to cast transparent proxy to type 'Program1.Loader'.
ローディングコードである:
try {
unload(dom,out loader,true);
dom=null;
AppDomainSetup dms = new AppDomainSetup();
dms.ConfigurationFile=Environment.CurrentDirectory+Path.DirectorySeparatorChar+"Program1.exe.config";
dms.ApplicationBase=Environment.CurrentDirectory+Path.DirectorySeparatorChar+"Plugins";
Evidence ev = AppDomain.CurrentDomain.Evidence;
dom=AppDomain.CreateDomain("PluginManager",ev,dms);
AssemblyName an = AssemblyName.GetAssemblyName(Environment.CurrentDirectory+"\\Plugins\\PluginManager.dll");
ObjectHandle obj = dom.CreateInstance(an.FullName,"PluginManager.PluginManager");
loader = (Loader)obj.Unwrap();
loader.LoadAssembly(@"PluginManager.dll");
if(!suppressOutput)
Console.WriteLine("Reload successful.");
}
catch(Exception e) {
unload(dom,out loader,true);
loader=null;
Console.WriteLine("PluginManager failed loading. Enter \"reload\" to try again.\n");
Console.Write(e+"\n\n");
}
エラーがスローされる場合、この行は:
loader = (Loader)obj.Unwrap();
外部DLLはほとんどないコードを有しますこれは概念の証明であるからです。次のようになります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PluginManager {
public class PluginManager:MarshalByRefObject {
public void run(string comm) {
Console.WriteLine(comm);
}
}
}
編集:これはローダークラスのコードです。
class Loader:MarshalByRefObject {
private Assembly _assembly;
public override object InitializeLifetimeService() {
return null;
}
public void LoadAssembly(string path) {
_assembly=Assembly.Load(AssemblyName.GetAssemblyName(path));
}
public object ExecuteStaticMethod(string typeName,string methodName,params object[] parameters) {
Type type = _assembly.GetType(typeName);
MethodInfo method = type.GetMethod(methodName,BindingFlags.Static|BindingFlags.Public);
return method.Invoke(null,parameters);
}
}
私はローダキャストが含まれるように、コードを更新しました。少しのコードで回答を説明できますか?私はあなたが何をしたいのか分からない。 – Bioniclegenius
編集ありがとう!しかし、ローダーはメインプログラムにあります。 DLLからロードしようとするとCreateInstanceが失敗しませんか? – Bioniclegenius
しかし、Loaderをロードしようとしないときは、PluginManagerをロードしようとします。それが問題です。これがAppDomain.CreateInstanceに渡しています。 –