从远程装配加载接口

时间:2014-10-08 15:20:00

标签: c# .net winforms c++-cli client-server

我目前正在开发客户端 - 服务器应用程序。 它应该从模块加载接口并在它自己的窗口中显示它们。 但有时我需要插入远程模块。 我可以从模块运行表单(所有操作都有效)而无需在磁盘上加载模块文件吗? 谢谢。

1 个答案:

答案 0 :(得分: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;
    }
}