2013-05-30 20 views
0

采取以下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调用在这个新程序集中实现的所需方法。

+0

保持源代码的形式全部“可移动代码”,这样你就不需要通过反射来“恢复”了它,而且你可以运输到任何地方编译你喜欢... – Yahia

+1

那么为什么不使用可卸载的插件?所以机器B总是可以加载/卸载它们,你需要的只是一个插件主机,它能够做到这些(通过名称调用插件的方法)。 –

+1

这听起来很合理:将整个程序集(及其依赖项)从机器A传输到B,将其加载到AppDomain中,并按名称调用方法。 – derabbink

回答

2

注意 - 这是不是一个真正的答案(的种类),更多的是吹毛求疵修正..

当你说“既然序列化的代表是不可能的”,这是不是严格真,尽管我不会推荐这样做。这个示例代码有效地将 “序列化” 的委托:

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远程处理:实际上是通过代理远程调用远程对象上程序集中的方法。

+0

我同意您的一般安全问题,但我的系统将在物理隔离的网络上运行。建议的系统将用于测试分布式应用黑盒式;运输代码包含测试说明。 – derabbink

相关问题