Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从远程程序集加载接口_C#_.net_Winforms_C++ Cli_Client Server - Fatal编程技术网

C# 从远程程序集加载接口

C# 从远程程序集加载接口,c#,.net,winforms,c++-cli,client-server,C#,.net,Winforms,C++ Cli,Client Server,我目前正在开发客户机-服务器应用程序。 它应该从模块中加载接口,并在自己的窗口中显示它们。 但有时我需要插入远程模块。 我是否可以从模块运行表单(所有操作都正常),而不将模块文件加载到磁盘上? 谢谢。是的,您可以加载从远程计算机发送的程序集(我不会在这里讨论这一点的安全含义,我至少会检查签名): 在C++/CLI中(您的问题中不清楚您使用的是什么语言): 请注意,这是一个非常简单的实现,因为每个实例都是不同的(如果您多次加载同一个插件),而且它在资源(主内存)方面也是可扩展的。您应该保留程序集缓

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

是的,您可以加载从远程计算机发送的程序集(我不会在这里讨论这一点的安全含义,我至少会检查签名):

在C++/CLI中(您的问题中不清楚您使用的是什么语言):

请注意,这是一个非常简单的实现,因为每个实例都是不同的(如果您多次加载同一个插件),而且它在资源(主内存)方面也是可扩展的。您应该保留程序集缓存:

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;
    }
}
专用静态字典\u缓存组件=
新字典();
公共静态程序集LoadRemoteAssembly(字符串url)
{
锁(缓存组件)
{
如果(_cachedAssemblies.ContainsKey(url))
返回缓存组件[url];
var data=new WebClient.DownloadData(url);//例如。。。
var assembly=assembly.Load(数据);
_添加(url,程序集);
返回组件;
}
}

Adriano:谢谢。那么,我将使用WebClient下载它,但是要下载到内存中吗?还有一个问题:我可以从中只加载一个类(只加载表单)还是只加载整个文件?谢谢。那么,我将使用WebClient下载它,但是要下载到内存中吗?还有一个问题:我可以从中只加载一个类(只加载表单)还是只加载整个文件?@Michail是的,就是这样。请注意不要在内存中多次下载和加载同一程序集(以避免可能产生的奇怪行为并减少内存使用)。不,您不能只加载一种类型,如果您下载一个程序集,它将被完全加载到内存中(但JIT编译器将足够智能,可以只编译所需的内容)。请注意,依赖项也必须在客户端可用。还有其他技术可以实现类似的结果,但如果没有更详细的上下文,我就不能说得更具体。在对用户进行身份验证后,我仅使用指定的模块对其进行配置。一些模块可以放置在远程工作站上。我想避免加载不必要的东西,减少网络负载。我无法预先知道未来模块的大小。它们将在应用程序的整个生命周期中添加。通过比较WebClient,可以通过其他方法完成吗?如果它是一个配置工具,您可以只下载它的定义。用户界面可以在客户端动态构建,而不需要深入了解它正在配置什么。作为替代方案,远程模块可能只向客户端发送一个小程序集,该程序集具有最小的逻辑和用于配置的用户界面。在这种情况下,它们将按需下载(或在后台线程中)并在本地缓存(仅当程序集版本号更改时才需要刷新)。客户端优先查询版本(使用另一个URL、Web服务或查询参数)和远程模块使用限定的程序集名称进行应答。若缓存中不存在该程序集(或版本不同),则开始新的下载,程序集将保存到本地磁盘(并从加载的磁盘保存),并且除非将来再次更改版本,否则不会覆盖该程序集。
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;
    }
}