別のドメインに .dll(プラグイン) をロードする必要があります。メインアプリでは、プラグインのタイプについては何も知りませんが、いくつかのメソッドで共通インターフェイス ICommonInterface を実装しているだけです。インターフェイス型のインスタンスを作成できないため、このコードは役に立ちません。
AppDomain domain = AppDomain.CreateDomain("New domain name");
//Do other things to the domain like set the security policy
string pathToDll = @"C:\myDll.dll"; //Full path to dll you want to load
Type t = typeof(TypeIWantToLoad);
TypeIWantToLoad myObject = (TypeIWantToLoad)domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName);
私の質問は、作成したいタイプを実装するインターフェイス名しか知らない場合、新しいドメインにアセンブリをロードしてインスタンスを取得する方法です。
更新: これが私のコードです: MainLib.dll
namespace MainLib
{
public interface ICommonInterface
{
void ShowDllName();
}
}
PluginWithOutException.dll
namespace PluginWithOutException
{
public class WithOutException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
Console.WriteLine("PluginWithOutException");
}
}
}
PluginWithException.dll
namespace PluginWithException
{
public class WithException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
Console.WriteLine("WithException");
throw new NotImplementedException();
}
}
}
そして主なアプリケーション:
static void Main(string[] args)
{
string path = @"E:\Plugins\";
string[] assemblies = Directory.GetFiles(path);
List<string> plugins = SearchPlugins(assemblies);
foreach (string item in plugins)
{
CreateDomainAndLoadAssebly(item);
}
Console.ReadKey();
}
public static List<string> SearchPlugins(string[] names)
{
AppDomain domain = AppDomain.CreateDomain("tmpDomain");
domain.Load(Assembly.LoadFrom(@"E:\Plugins\MainLib.dll").FullName);
List<string> plugins = new List<string>();
foreach (string asm in names)
{
Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName);
var theClassTypes = from t in loadedAssembly.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
if (theClassTypes.Count() > 0)
{
plugins.Add(asm);
}
}
AppDomain.Unload(domain);
return plugins;
}
プラグインとメイン アプリには、MainLib.dll への参照があります。主な目的は、アセンブリを既定のドメインにロードするのではなく、別のドメインにロードすることです。したがって、アセンブリが必要ない場合は、Unload() ドメインを使用してアプリケーションからすべてのプラグインをアンロードします。
今のところ、例外はFileNotFoundException, Could not load file or assembly 'PluginWithException, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.)
文字列にありますAssembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName);
(PluginWithException という名前のプラグインを読み込もうとしています)。システムを除くプラグインのすべての依存関係を削除しました。このドメインに System.dll をロードしました (正しくロードされ、ドメイン内にあります)。それでもプラグインをドメインにロードできません。また、PluginWithException には 2 つの依存関係 (mscorlib と MainLib) があり、それらすべてがこのドメインに読み込まれていることも確認しました。
更新:ここで、この質問に詳細を尋ねました。