Загрузить интерфейс из удаленной сборки

1

В настоящее время я разрабатываю клиент-серверное приложение. Он должен загружать интерфейсы из модулей и показывать их внутри собственного окна. Но иногда мне нужно подключить удаленный модуль. Могу ли я запустить форму из модуля (со всеми действиями) без загрузки файла модуля на диск? Спасибо.

  • 0
    Адриано: спасибо. Итак, я буду загружать его с WebClient, но в память? Еще один вопрос: могу ли я загрузить из него только один класс (только форму) или только целый файл?
Теги:
winforms
c++-cli
client-server

1 ответ

1
Лучший ответ

Да, вы можете загрузить сборку, отправленную с удаленного компьютера (я не буду обсуждать здесь последствия для безопасности этого, я бы, по крайней мере, проверить подпись):

var data = new WebClient.DownloadData(url); // For example...
var assembly = Assembly.Load(data);

В C++/CLI (в вашем вопросе непонятно, на каком языке вы используете):

array<Byte>^ data = (gcnew WebClient())->DownloadData(url);
Assembly^ assembly = Assembly::Load(data);

Теперь у вас есть сборка, и вы можете что-то загрузить с нее, например (просто для иллюстрации):

var plugins = assembly.GetExportedTypes()
    .Where(x => typeof(IYourContract).IsAssignableFrom(x) && !x.IsAbstract)
    .Select(x => (IYourContract)Activator.CreateInstance(x));

Обратите внимание, что это очень наивная реализация, потому что каждый экземпляр будет другим (если вы загружаете один и тот же плагин несколько раз), а также экспансивным с точки зрения ресурсов (первичная память). Вы должны хранить кеш сборки:

private static Dictionary<string, Assembly> _cachedAssemblies =
    new Dictionary<string, Assembly>();

public static Assembly LoadRemoteAssembly(string url)
{
    lock (_cachedAssemblies)
    {
        if (_cachedAssemblies.ContainsKey(url))
            return _cachedAssemblies[url];

        var data = new WebClient.DownloadData(url); // For example...
        var assembly = Assembly.Load(data);

        _cachedAssemblies.Add(url, assembly);

        return assembly;
    }
}
  • 0
    благодарю вас. Итак, я буду загружать его с WebClient, но в память? Еще один вопрос: могу ли я загрузить из него только один класс (только форму) или только целый файл?
  • 0
    @ Михаил да, вот и все. Пожалуйста, позаботьтесь о том, чтобы не загружать и не загружать в память одну и ту же сборку более одного раза (чтобы избежать странных действий, которые это может вызвать, и уменьшить использование памяти). Нет, вы не можете загрузить только один тип, если вы загрузите одну сборку, она будет полностью загружена в память (но JIT-компилятор будет достаточно умен, чтобы компилировать только то, что нужно). Обратите внимание, что зависимости должны быть доступны также на стороне клиента. Существуют и другие методы для достижения аналогичных результатов, но я не могу быть более конкретным без гораздо более подробного контекста.
Показать ещё 10 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню