Мне нужно загрузить .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);
Мой вопрос, как я могу загрузить сборку в новом домене и получить экземпляр, если я знаю только имя интерфейса, который реализует тип я хочу создать.
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), Я удалить все зависимости в плагинах, кроме арматуры системы, я загрузил System.dll в этой области (она загружена правильно и он находится в домене), но все еще не могут загрузить плагины в домен. Также я проверил, что PluginWithException имеет 2 зависимости - mscorlib и MainLib, и все они загружены в этот домен.
ОБНОВЛЕНИЕ: Here Я задал этот вопрос более подробно.
Хорошо, но это сборки будут загружены в домене по умолчанию и будет жить там, пока я не закрыть приложение. И я хочу загрузить сборку в другом домене и выгрузить ее со всеми сборками, когда мне это нужно. –
И проблема в том, что я не могу использовать код 'Assembly a = anotherDomain.Load (Assembly.LoadFrom (path) .FullName);', он выдает исключение fileNotFountException, но DLL существует по этому пути –
Справедливые точки.Это не так просто, как кажется. Я переработал свой ответ. – Dan