2013-05-30 53 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

相關問題