Я пытаюсь создать фрейм плагина и загружать зависимости путем отражения в C#. Моя текущая реализация такова:C# Сборка Create Instance в дочернем домене
public interface IPlugin : IDisposable
{
void Run();
}
public interface IPluginProxy : IDisposable
{
void RunProxy();
void LoadDependencies(string pluginDirectoryPath, AppDomain pluginDomain);
}
public class PluginProxy : MarshalByRefObject, IPluginProxy, IDisposable
{
private List<IPlugin> pluginTypes = null;
public void ProcessProxy()
{
//loop thorough plugin types and call Run on all plugins
foreach(var pluginType in pluginTypes)
{
pluginType.Run();
}
}
public void LoadDependencies(string pluginDirectoryPath, AppDomain pluginDomain)
{
pluginTypes = Utility.LoadAssembliesAndGetPluginTypes(pluginDirectoryPath, pluginDomain);
}
//TODO:
public void Dispose(){}
}
public Class Utility
{
public static List<IPlugin> LoadAssembliesAndGetPluginTypes(string pluginDirectoryPath, AppDomain pluginDomain)
{
try
{
var pluginTypes = new List<IPlugin>();
var pluginsDirectory = new DirectoryInfo(pluginDirectoryPath);
var files = pluginsDirectory.GetFiles("*.dll", SearchOption.TopDirectoryOnly);
foreach (FileInfo file in files)
{
// Load the assembly into the child application domain.
Assembly assembly = pluginDomain.Load(AssemblyName.GetAssemblyName(file.FullName));
var iPluginTypes = zGetTypes(assembly);
pluginTypes.AddRange(iPluginTypes.ToList());
}
return pluginTypes;
}
catch (Exception ex)
{
throw ex;
}
}
private static IEnumerable<IPlugin> zGetTypes(Assembly assembly)
{
var myPlugins = from y in assembly.GetTypes()
where y.IsClass && y.GetInterface("IPlugin") != null &&
y.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(y) as IPlugin;
return myPlugins;
}
}
У меня есть служба Windows, которая создает новый домен приложения. Затем он получает PluginProxy и вызывает LoadDependencies и ProcessProxy. Заметьте, что я пытаюсь загрузить зависимости в дочерний домен.
Проблема с методом zGetTypes. Метод способен находить типы IPlugin (это показывает intellisense). Однако типы не инициализируются (null), даже если вы вызываете Activator.CreateInstance.
Обратите внимание: zGetTypes не может создать экземпляр типа IPlugin, если я в дочернем домене.
Монтажная сборка = плагинDomain.Load (AssemblyName.GetAssemblyName (file.FullName));
Если я не создаю отдельный appdomain и просто загружаю сборку в основной appdomain, создается создание экземпляра экземпляра. В моем случае приложение appdomain создает дочернее приложение. Я хочу взять на себя ответственность за загрузку сборок плагина в прокси. Прокси получается из MarshalByRefObject, поэтому я могу создать экземпляр и развернуть его со стороны службы Windows.
Служба затем делегирует управление загрузками и жизненным циклом плагинов на прокси. Прокси-сервер получит контекст дочернего appdomain через параметр метода LoadDependencies.
Любые идеи, почему бы не создать экземпляр (ы) IPlugin?