我需要在另一个域中加载.dll(插件)。在主应用程序中,我对插件类型一无所知,只是他们用一些方法实现了通用接口ICommonInterface。所以这段代码没有帮助,因为我无法用接口类型创建一个实例。将DLL加载到单独的具有已知通用接口的AppDomain中
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);
我的问题是如何能在新的领域加载程序集,并得到例如,如果我知道它实现了I型只希望创建接口名称。
UPDATE: 这里是我的代码: 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。主要目标是不要在默认域中加载程序集,而是将它们加载到其他域,所以当我不需要它们时,我只需卸载()域并从应用程序卸载所有插件。
对于现在的例外是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插件),我已经删除插件的所有依赖,exept系统,我在这个领域加载System.dll中(它加载正确的,它在域中),但仍然不能将插件加载到域中。此外,我检查,PluginWithException有2个依赖项 - mscorlib和MainLib,并将它们全部加载到此域。
更新:Here我问了这个问题的更多细节。
好吧,不过这集将在默认域加载,将生活在那里,直到我关闭应用程序。我想在另一个域中加载程序集,并在需要时使用所有程序集卸载它。 – 2013-05-03 15:52:44
问题在于我无法使用代码'Assembly a = anotherDomain.Load(Assembly.LoadFrom(path).FullName);',它抛出fileNotFountException,但是.dll存在于此路径 – 2013-05-03 15:55:38
Fair point。这并不像看起来那么直截了当。我重新回答了我的答案。 – Dan 2013-05-03 16:11:21