2008-12-06 17 views
18

मैं .NET 3.5 के साथ सी # का उपयोग कर रहा हूं। क्या कोड के ब्लॉक को क्रमबद्ध करना संभव है, इसे कहीं भी प्रेषित करना, इसे deserialize, और फिर इसे निष्पादित करना संभव है?क्या सी # कोड ब्लॉक को क्रमबद्ध करना संभव है?

इस का एक उदाहरण उपयोग होगा:

Action<object> pauxPublish = delegate(object o) 
{ 
    if (!(o is string)) 
    { 
     return; 
    } 
    Console.WriteLine(o.ToString()); 
}; 
Transmitter.Send(pauxPublish); 

कुछ सुदूर कार्यक्रम कर रही है:

var action = Transmitter.Recieve(); 
action("hello world"); 

मेरे अंतिम लक्ष्य एक अलग प्रक्रिया में मनमाने ढंग से कोड निष्पादित करने के लिए सक्षम होने के लिए है (जो है कोड का कोई पूर्व ज्ञान नहीं)।

+0

क्लाइंट के लिए काम करते समय, जो हर दिन हजारों फाइल आयातों को दो सौ स्रोतों से संभालता था, मैंने एक सामान्य आयात उपकरण बनाया जहां उन्नत उपयोगकर्ताओं को फ़ाइल कॉलम को परिभाषित करने और इनपुट को बदलने के लिए सी # की एक पंक्ति दर्ज करने की अनुमति थी उपयुक्त प्रकार/प्रारूप के लिए मूल्य। एक बार नई परिभाषा को सहेजने के बाद, हम इस स्रोत के लिए आयात कक्षा को गतिशील रूप से संकलित करेंगे, फिर नई फाइलें आने पर इसे निष्पादित करें। 50 या इतने आम मामलों के साथ ऑटो-पूर्ण करने योग्य, यह आश्चर्यजनक रूप से अच्छी तरह से काम करता है और परिवर्तन के बहुत सारे अनुरोधों को बचाता है, साथ ही परिमाण के क्रम से आयात की गति में सुधार करता है। – Basic

उत्तर

15

हाँ !!!

हमने प्रदर्शन के एक बहुत ही वास्तविक मामले के लिए ऐसा किया है। रनटाइम पर ऐसा करना या डीएसएल का उपयोग करना प्रदर्शन के कारण एक विकल्प नहीं था।

हम कोड को एक असेंबली में संकलित करते हैं, और आईएल को विधि से बाहर निकाल देते हैं।इसके बाद हम इस विधि से जुड़े सभी मेटाडेटा प्राप्त करते हैं और एक्सएमएल के माध्यम से पूरी गड़बड़ी को क्रमबद्ध करते हैं, इसे संपीड़ित करते हैं, और इसे हमारे डेटाबेस में डाल देते हैं।

पुन: हाइड्रेशन समय पर, हम डायनामिक मोड कक्षा का उपयोग करके मेटाडेटा के साथ आईएल का पुनर्गठन करते हैं, और इसे निष्पादित करते हैं।

हम गति के कारण ऐसा करते हैं। हमारे पास कोड के हजारों छोटे ब्लॉक हैं। दुर्भाग्यवश, कोड के ब्लॉक को संकलित करने और इसे फ्लाई पर चलाने के लिए कम से कम 250 एमएस लगता है, जो हमारे लिए बहुत धीमा है। हमने यह दृष्टिकोण लिया, और यह वास्तव में अच्छी तरह से काम कर रहा है। रन-टाइम पर, विधि को पुनर्स्थापित करने और इसे चलाने के लिए एक अनूठा समय लगता है।

केवल एक चीज रखने के लिए ... हस्ताक्षरित असेंबली और बिना हस्ताक्षर असेंबली धारावाहिक विधि डेटा मिश्रण नहीं कर सकते हैं।

+0

यह वह तरीका था जिस पर मैं आया था और काम कर रहा हूं। सबसे बड़ी समस्या बाइट सरणी को परिवर्तित करने लगती है कि विधिबॉडी प्रतिबिंब के साथ उपयोग करने के लिए ओपोड्स में देता है। प्रवेश करें। मैं http://weblogs.asp.net/rosherove/archive/2006/04/25/methodsvisualizer.aspx देख रहा हूं जो मदद कर सकता है। – ICR

+0

o0o यह उस दृष्टिकोण की तरह लगता है जिसे मैं ढूंढ रहा हूं। यदि आपके पास सोचने से संबंधित कोई और संसाधन हैं, तो लिंक की बहुत सराहना की जाएगी :) – NoizWaves

+3

यदि आपने जो किया है, तो मैं अपना मन नहीं बना सकता अद्भुत या भयानक है। संभवतः दोनों। – Anthony

1

इसे एक अलग असेंबली में संकलित करें, असेंबली भेजें, अन्य प्रक्रिया को लोड करें।

आप सुरक्षा प्रभावों पर विचार करना चाहेंगे।

अद्यतन: एक और विचार एक अभिव्यक्ति पेड़ पैदा करते हैं और यह क्रमानुसार करने इस पुस्तकालय का उपयोग करने के होगा:

http://www.codeplex.com/metalinq/

3

तुम भी एक स्ट्रिंग के रूप में यह भेज सकता है तो यह संकलन करने CodeDomProvider उपयोग करते हैं, एक ही परिणाम। मैं इस प्रकार कोड का एक उदाहरण सा है:

using System; 
using System.CodeDom.Compiler; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.IO; 
using System.Linq; 
using System.Reflection; 
using System.Text; 
using Microsoft.CSharp; 

namespace DynamicCodeApplication 
{ 
    class azCodeCompiler 
    { 
     private List<string> assemblies; 

     public azCodeCompiler() 
     { 
      assemblies = new List<string>(); 
      scanAndCacheAssemblies(); 
     } 

     public Assembly BuildAssembly(string code) 
     { 

      CodeDomProvider prov = CodeDomProvider.CreateProvider("CSharp"); 
      string[] references = new string[] { }; // Intentionally empty, using csc.rsp 
      CompilerParameters cp = new CompilerParameters(references) 
             { 
              GenerateExecutable = false, 
              GenerateInMemory = true 
             }; 
      string path = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); 
      cp.CompilerOptions = "@" + path + @"\csc.rsp"; 
      CompilerResults cr = prov.CompileAssemblyFromSource(cp, code); 

      foreach (CompilerError err in cr.Errors) 
      { 
       Console.WriteLine(err.ToString()); 
      } 
      return cr.CompiledAssembly; 
     } 

     public object ExecuteCode(string code, 
            string namespacename, string classname, 
            string functionname, bool isstatic, params object[] args) 
     { 
      object returnval = null; 
      Assembly asm = BuildAssembly(code); 
      object instance = null; 
      Type type = null; 
      if (isstatic) 
      { 
       type = asm.GetType(namespacename + "." + classname); 
      } 
      else 
      { 
       instance = asm.CreateInstance(namespacename + "." + classname); 
       type = instance.GetType(); 
      } 
      MethodInfo method = type.GetMethod(functionname); 
      returnval = method.Invoke(instance, args); 
      return returnval; 
     } 

     private void scanAndCacheAssemblies() 
     { 

      /* 
      foreach (string str in Directory.GetFiles(@"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727")) 
      { 
       if (str.Contains(".dll")) 
       { 
        foreach (string st in str.Split(new char[] { '\\' })) 
        { 
         if (st.Contains(".dll")) 
         { 
          assemblies.Add(st); 
         } 
        } 
       } 
      } 
      * */ 

      assemblies.Add("Accessibility.dll"); 
      assemblies.Add("AspNetMMCExt.dll"); 
      assemblies.Add("cscompmgd.dll"); 
      assemblies.Add("CustomMarshalers.dll"); 
      assemblies.Add("IEExecRemote.dll"); 
      assemblies.Add("IEHost.dll"); 
      assemblies.Add("IIEHost.dll"); 
      assemblies.Add("Microsoft.Build.Conversion.dll"); 
      assemblies.Add("Microsoft.Build.Engine.dll"); 
      assemblies.Add("Microsoft.Build.Framework.dll"); 
      assemblies.Add("Microsoft.Build.Tasks.dll"); 
      assemblies.Add("Microsoft.Build.Utilities.dll"); 
      assemblies.Add("Microsoft.Build.VisualJSharp.dll"); 
      assemblies.Add("Microsoft.CompactFramework.Build.Tasks.dll"); 
      assemblies.Add("Microsoft.JScript.dll"); 
      assemblies.Add("Microsoft.VisualBasic.Compatibility.Data.dll"); 
      assemblies.Add("Microsoft.VisualBasic.Compatibility.dll"); 
      assemblies.Add("Microsoft.VisualBasic.dll"); 
      assemblies.Add("Microsoft.VisualBasic.Vsa.dll"); 
      assemblies.Add("Microsoft.Vsa.dll"); 
      assemblies.Add("Microsoft.Vsa.Vb.CodeDOMProcessor.dll"); 
      assemblies.Add("Microsoft_VsaVb.dll"); 
      assemblies.Add("mscorlib.dll"); 
      assemblies.Add("sysglobl.dll"); 
      assemblies.Add("System.configuration.dll"); 
      assemblies.Add("System.Configuration.Install.dll"); 
      assemblies.Add("System.Data.dll"); 
      assemblies.Add("System.Data.OracleClient.dll"); 
      assemblies.Add("System.Data.SqlXml.dll"); 
      assemblies.Add("System.Deployment.dll"); 
      assemblies.Add("System.Design.dll"); 
      assemblies.Add("System.DirectoryServices.dll"); 
      assemblies.Add("System.DirectoryServices.Protocols.dll"); 
      assemblies.Add("System.dll"); 
      assemblies.Add("System.Drawing.Design.dll"); 
      assemblies.Add("System.Drawing.dll"); 
      assemblies.Add("System.EnterpriseServices.dll"); 
      assemblies.Add("System.Management.dll"); 
      assemblies.Add("System.Messaging.dll"); 
      assemblies.Add("System.Runtime.Remoting.dll"); 
      assemblies.Add("System.Runtime.Serialization.Formatters.Soap.dll"); 
      assemblies.Add("System.Security.dll"); 
      assemblies.Add("System.ServiceProcess.dll"); 
      assemblies.Add("System.Transactions.dll"); 
      assemblies.Add("System.Web.dll"); 
      assemblies.Add("System.Web.Mobile.dll"); 
      assemblies.Add("System.Web.RegularExpressions.dll"); 
      assemblies.Add("System.Web.Services.dll"); 
      assemblies.Add("System.Windows.Forms.dll"); 
      assemblies.Add("System.XML.dll"); 
      assemblies.Add("vjscor.dll"); 
      assemblies.Add("vjsjbc.dll"); 
      assemblies.Add("vjslib.dll"); 
      assemblies.Add("vjslibcw.dll"); 
      assemblies.Add("vjssupuilib.dll"); 
      assemblies.Add("vjsvwaux.dll"); 
      assemblies.Add("vjswfc.dll"); 
      assemblies.Add("VJSWfcBrowserStubLib.dll"); 
      assemblies.Add("vjswfccw.dll"); 
      assemblies.Add("vjswfchtml.dll"); 
      assemblies.Add("Accessibility.dll"); 
      assemblies.Add("AspNetMMCExt.dll"); 
      assemblies.Add("cscompmgd.dll"); 
      assemblies.Add("CustomMarshalers.dll"); 
      assemblies.Add("IEExecRemote.dll"); 
      assemblies.Add("IEHost.dll"); 
      assemblies.Add("IIEHost.dll"); 
      assemblies.Add("Microsoft.Build.Conversion.dll"); 
      assemblies.Add("Microsoft.Build.Engine.dll"); 
      assemblies.Add("Microsoft.Build.Framework.dll"); 
      assemblies.Add("Microsoft.Build.Tasks.dll"); 
      assemblies.Add("Microsoft.Build.Utilities.dll"); 
      assemblies.Add("Microsoft.Build.VisualJSharp.dll"); 
      assemblies.Add("Microsoft.CompactFramework.Build.Tasks.dll"); 
      assemblies.Add("Microsoft.JScript.dll"); 
      assemblies.Add("Microsoft.VisualBasic.Compatibility.Data.dll"); 
      assemblies.Add("Microsoft.VisualBasic.Compatibility.dll"); 
      assemblies.Add("Microsoft.VisualBasic.dll"); 
      assemblies.Add("Microsoft.VisualBasic.Vsa.dll"); 
      assemblies.Add("Microsoft.Vsa.dll"); 
      assemblies.Add("Microsoft.Vsa.Vb.CodeDOMProcessor.dll"); 
      assemblies.Add("Microsoft_VsaVb.dll"); 
      assemblies.Add("mscorlib.dll"); 
      assemblies.Add("sysglobl.dll"); 
      assemblies.Add("System.configuration.dll"); 
      assemblies.Add("System.Configuration.Install.dll"); 
      assemblies.Add("System.Data.dll"); 
      assemblies.Add("System.Data.OracleClient.dll"); 
      assemblies.Add("System.Data.SqlXml.dll"); 
      assemblies.Add("System.Deployment.dll"); 
      assemblies.Add("System.Design.dll"); 
      assemblies.Add("System.DirectoryServices.dll"); 
      assemblies.Add("System.DirectoryServices.Protocols.dll"); 
      assemblies.Add("System.dll"); 
      assemblies.Add("System.Drawing.Design.dll"); 
      assemblies.Add("System.Drawing.dll"); 
      assemblies.Add("System.EnterpriseServices.dll"); 
      assemblies.Add("System.Management.dll"); 
      assemblies.Add("System.Messaging.dll"); 
      assemblies.Add("System.Runtime.Remoting.dll"); 
      assemblies.Add("System.Runtime.Serialization.Formatters.Soap.dll"); 
      assemblies.Add("System.Security.dll"); 
      assemblies.Add("System.ServiceProcess.dll"); 
      assemblies.Add("System.Transactions.dll"); 
      assemblies.Add("System.Web.dll"); 
      assemblies.Add("System.Web.Mobile.dll"); 
      assemblies.Add("System.Web.RegularExpressions.dll"); 
      assemblies.Add("System.Web.Services.dll"); 
      assemblies.Add("System.Windows.Forms.dll"); 
      assemblies.Add("System.XML.dll"); 
      assemblies.Add("vjscor.dll"); 
      assemblies.Add("vjsjbc.dll"); 
      assemblies.Add("vjslib.dll"); 
      assemblies.Add("vjslibcw.dll"); 
      assemblies.Add("vjssupuilib.dll"); 
      assemblies.Add("vjsvwaux.dll"); 
      assemblies.Add("vjswfc.dll"); 
      assemblies.Add("VJSWfcBrowserStubLib.dll"); 
      assemblies.Add("vjswfccw.dll"); 
      assemblies.Add("vjswfchtml.dll"); 


      return; 
     } 
    } 
} 
+0

यह एक महान मदद टार्क्स होगा, धन्यवाद! इस विषय के साथ जारी है, क्या कोड के सी # ब्लॉक को स्ट्रिंग में बदलना संभव है? – NoizWaves

0

एक अन्य विकल्प DLR उपयोग कर रहा है, और निष्पादित करने के लिए कोड को बाधित ...

4

सामान्यतया कि एक बहुत बुरा विचार और एक बड़ा सुरक्षा छेद की तरह लगता है ।

आप किसी भी कोड को निष्पादित करने की कोई अन्य प्रक्रिया नहीं चाहते हैं। समझें कि आपको वास्तव में इसके लिए एक और डीएसएल बनाने और बनाने के लिए एक और प्रक्रिया की आवश्यकता है।

+0

बिलकुल, आप उस कॉलर पर भरोसा नहीं कर सकते जिसे आप वास्तव में एक डीएसएल के साथ आने के लिए तैयार हैं। एमजी्राममार और ओस्लो पर एक नज़र डालें। –

+0

मनमाने ढंग से कोड निष्पादित करना और/या डेटाबेस में इसे संग्रहीत करना ... संभवतः गलत क्या हो सकता है? मेरे लिए एक विरोधी पैटर्न की तरह प्रतीत नहीं होता ;-) –

7

आप अपनी परियोजना में IronPython का उपयोग करने का प्रयास कर सकते हैं। पाइथन में जो भी आप पूछ रहे हैं, वह करने के लिए trivial है। पायथन कोड आपके सी # विधियों को कॉल कर सकता है। सुरक्षा के लिए, आप किसी प्रकार के प्रतिबंधित वातावरण में कोड निष्पादित कर सकते हैं (एक उदाहरण RestrictedPython है)।

1

यह एक दिलचस्प चुनौती है, लेकिन आपको शायद यह वर्णन करना चाहिए कि आप ऐसा क्यों करना चाहते हैं, क्योंकि आपके उद्देश्य के आधार पर कई अलग-अलग दृष्टिकोण हैं। चूंकि humpohl बताते हैं, कुछ गंभीर सुरक्षा मुद्दों भी हैं।

"सीरियलाइज्ड कोड" आपकी आवश्यकताओं के आधार पर केवल स्रोत कोड या संकलित असेंबली हो सकता है। आपको शायद एक अलग कोड क्रमबद्धता प्रारूप का उपयोग करने की आवश्यकता नहीं है।

यदि आप गतिशील रूप से कोड जेनरेट करना चाहते हैं और इसे पास करना चाहते हैं, तो आप CodeDOM का उपयोग करके कोड उत्पन्न कर सकते हैं और इसे संकलित कर सकते हैं। हालांकि, आपको सबसे अधिक मनमाने ढंग से कोड उत्पन्न करने की आवश्यकता नहीं है।

संबंधित मुद्दे