2014-10-08 4 views
1

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

+0

Adriano: спасибо. Итак, я загружу его с помощью WebClient, но в память? Еще один вопрос: могу ли я загрузить только один класс (только форму) из него или всего файла? – Michail

ответ

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, но в память? Еще один вопрос: могу ли я загрузить только один класс (только форму) из него или всего файла? – Michail

+0

@Michail да, вот и все. Пожалуйста, позаботьтесь о том, чтобы не загружать и загружать в память одну и ту же сборку более одного раза (во избежание странных действий, которые этот _may_ производит и уменьшает использование памяти). Нет, вы не можете загрузить только один тип, если вы загружаете одну сборку, она будет полностью загружена в память (но JIT-компилятор будет достаточно умным, чтобы скомпилировать только то, что нужно). Обратите внимание, что зависимости должны быть доступны и на стороне клиента. Существуют другие методы для достижения аналогичных результатов, но я не могу быть более конкретным без более подробного контекста. –

+0

Существует более подробная информация: это центральная панель инструментов. После аутентификации пользователя я настраиваю его только с использованием указанных модулей. Некоторые модули могут быть размещены на удаленных станциях. Я хочу избежать загрузки ненужных вещей и снижения сетевой нагрузки. Я не могу заранее знать размер будущих модулей. Они будут добавлены в течение всего жизненного цикла приложения. Можно ли это сделать другими методами, сравнивая WebClient? – Michail

Смежные вопросы