我可以在“临时”中发布现有的实现吗?组装

本文关键字:实现 组装 布现 临时 我可以 | 更新日期: 2023-09-27 18:16:19

用下面的c#代码

namespace lib.foo {
  public class A {
    public A (int x) {}
    public int GetNumber() { return calculateNumber(); }
    private int calculateNumber() { return lib.bar.B.ProduceNumber(); }
    public void irrelevantMethod() {}
  }
}
namespace lib.bar {
  public class B {
    public static int ProduceNumber() { return something; }
    public void IrrelevantMethod() {}
  }
}

我想生成一个包含lib.foo.A.GetNumber()功能的程序集,存储它,然后动态加载它,然后执行它。
为了使它工作,我需要一个程序,可以跟踪所有必需的依赖项(如下所列),并在一个程序集中发出它们——包括它们的实现(!)。

 * lib.foo.A(int)
 * lib.foo.A.getNumber()
 * lib.foo.A.calculateNumer()
 * lib.bar.B.ProduceNumber()

可以做到吗?如何?

如果有人想知道,我想建立一个系统,机器a告诉机器B(使用WCF)做什么。由于序列化委托是不可能的,我的计划是

1)将一个装配件从A机传送到B机,

2)将程序集装入B机,

3)让机器A指令机器B调用所需的方法,该方法在这个新的汇编中实现。

我可以在“临时”中发布现有的实现吗?组装

注意-这不是一个真正的答案,更多的是一个挑剔的纠正(各种).

当你说"因为序列化委托是不可能的",这不是严格正确,尽管我不建议这样做。下面的示例代码有效地"序列化"一个委托:

void Main()
{
    Func<int,int> dlgt = FuncHolder.SomeMethod;
    var ser = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    byte[] buffer;
    using(var ms = new MemoryStream())
    {
        ser.Serialize(ms, dlgt);
        buffer = ms.ToArray();
    }
    Console.WriteLine("{0} was serialized to {1} bytes", dlgt.GetType().Name, buffer.Length);
    using(var ms = new MemoryStream(buffer))
    {
        dynamic whatzit = ser.Deserialize(ms);
        whatzit(1);
    }
}
[Serializable]
public struct FuncHolder
{
    public static int SomeMethod(int i)
    {
        Console.WriteLine("I was called with {0}, returning {1}", i, i+1);
        return i+1;
    }
}
输出:

Func`2 was serialized to 978 bytes
I was called with 1, returning 2
然而,我必须强调,您可能不应该这样做。:)

对于最初的问题:

我会非常小心地传输和执行任意代码,特别是在生产环境中;安全漏洞的可能性相当大,主要是通过注入路径。举个例子,如果你采纳了上面的建议之一,并且只是通过源代码来动态地执行,那么就很难阻止有人向你的"给我代码来运行"服务中注入什么。

你真的需要在这里说出你的确切需求,才能真正想出一个"好的"解决方案,因为有多种方法可以实现相同的基本想法:

  • 如前所述,将实际的源代码传递给服务以加载/编译/执行,可能在"沙盒"中用于某些安全/保护

  • 将所有可执行代码路径分布在一个共享的插件/程序集中,由一些受信任的进程推送到所有远程服务器,并将执行代码减少到单个"DoWork"方法调用(即,将所有细节包装在插件中)

  • 拼凑一个粗略的DSL或其他类型的伪语言,限制它能做什么/不能做什么,并传递源代码。

  • 依赖于。net远程:实际上是通过代理在远程对象上远程调用程序集中的方法。