Использование MarshalByRefObject без необходимости загружать сборки, загруженные во второй AppDomain

У меня есть 2 домена приложений

1: host 
2: plugin

Теперь у меня есть PluginLoader который наследует MarshalByRefObjectпотому что я хочу вернуть количество плагинов, загруженных в этот домен. Я использую его для загрузки плагинов в плагин-AppDomain с помощью domain.DoCallBack(new CrossAppDomainDelegate(loader.LoadPlugin));В плагине AppDomain я загружаю плагин, который ссылается на EntityFramework. Теперь мой host-AppDomain хочет загрузить EntityFramework.dll тоже, когда я загружаю плагин в plugin-AppDomain, который использует EntityFramework.dll, Это происходит только тогда, когда мой PluginLoader продолжается MarshalByRefObject, Когда PluginLoader не расширяет MarshalByRefObject (т.е. он сериализуется для выполнения вызова), хост-домен приложения не хочет загружаться EntityFramework.dll,

Поэтому мой вопрос: возможно ли сделать вызов в другой домен приложений, используя MarshalByRefObject, без необходимости загружать все сборки, запрошенные другим доменом приложений? Или, в более общем плане: как сделать вызов в AppDomain и вернуть значение, не загружая сборки, запрошенные другим AppDomain?

Вот мой код для справки:

static void Main(string[] args)
{
    var pluginPath = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath) + "\\Plugins";
    var files = Directory.GetFiles(pluginPath, "*.dll")
        .Where(f => f.EndsWith("ArtNet.dll")); // just want to test this one plugin atm
    Console.WriteLine("Found {0} files", files.Count());
    foreach (var file in files)
    {
        Console.WriteLine("Loading {0}", file);
        Console.WriteLine("Creating AppDomain");
        var setup = new AppDomainSetup();
        setup.PrivateBinPath = pluginPath;
        var domain = AppDomain.CreateDomain(file, null, setup);

        var loader = new PluginLoader { File = file, HubUri = hubUri };
        domain.DoCallBack(new CrossAppDomainDelegate(loader.LoadPlugin));

        if (loader.NumberOfLoadedPlugins > 0)
        {
            Console.WriteLine("Loaded {0} plugins from {1}", loader.NumberOfLoadedPlugins, file);
            appDomains.Add(file, domain);
        }
        else
        {
            Console.WriteLine("{0} did not contain any plugins, unloading AppDomain", file);
            AppDomain.Unload(domain);
            Console.WriteLine("Appdomain Unloaded for file {0}", file);
        }

    }

    Console.ReadKey();
}

И прокси

[Serializable]
public class PluginLoader : MarshalByRefObject
{
    public string File { get; set; }

    public string HubUri { get; set; }

    public int NumberOfLoadedPlugins { get; set; }

    public void LoadPlugin()
    {
        var plugins = new List<IPlugin>();

        Console.WriteLine("Loading Assembly");
        var pluginAssembly = Assembly.LoadFile(File);
        Console.WriteLine("Assembly loaded");
        var pluginTypes = pluginAssembly.ExportedTypes.Where(t => t.GetInterfaces().Any(i => i.Equals(typeof(IPlugin))));
        Console.WriteLine("Found {0} types implementing IPlugin", pluginTypes.Count());
        foreach (var pluginType in pluginTypes)
        {
            try
            {
                Console.WriteLine("Looking for a parameterless Constructor in {0}", pluginType.Name);
                var constructor = pluginType.GetConstructor(Type.EmptyTypes);
                if (constructor != null)
                {
                    Console.WriteLine("Found a parameterless constructor");
                    var plugin = (IPlugin)constructor.Invoke(null);
                    plugins.Add(plugin);
                    Console.WriteLine("Plugin of type {0} created", pluginType.Name);
                    plugin.StartAsync(HubUri).Wait();
                    Console.WriteLine("{0}.StartAsync({1}) called", pluginType.Name, HubUri);
                }
                else
                    Console.WriteLine("No Constructor found");
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception occured");
                Console.WriteLine(e);
            }
        }

        PluginRegister.Plugins.AddRange(plugins);
        NumberOfLoadedPlugins = plugins.Count;
    }
}

0 ответов

Другие вопросы по тегам