c# prevajalnik

Pozdravljeni!

Imam sledeč problem. Rad bi naredi, da mi program bral c# funkcije (npr. Math.abs(x), kjer je x seznam parametrov, ki jih dobim iz programa) iz xml datoteke. Tukaj se pa pojavi problem prevajanja. Slišal sem, da se da to rešiti tako, da napišeš script (npr. c#), ki se izvrši ob zagonu programa in v bistvu izvede prevajanje. Morda kdo ve o tem kaj več oz. pozna kakšno drugo rešitev.

Hvala

Matjaž

Avtor: o-MA-n-tjaz, objavljeno na portalu SloDug.si (Arhiv)

Leave a comment

Please note that we won't show your email to others, or use it for sending unwanted emails. We will only use it to render your Gravatar image and to validate you as a real person.

damjank
damjank - četrtek, 19. oktober 2006

Sem imel pred časom podoben problem - dinamično prevajanje c# kode iz datoteke XML (naknadno dodajanje funkcionalnosti brez novega grajenja z VS.NET) in nalaganje zbira v trenutno aplikacijsko domeno.Sistem ob zagonu preveri XML datoteko, če je njeno stanje od prejšnjega zagona spremenjeno, se izvede dinamično prevajanje kode.Npr. datoteka XML s programsko kodo za dinamično prevajanje:<?xml version="1.0" encoding="utf-8" ?><runtimeCode>  <outputAssembly>bin/RuntimeCode.dll</outputAssembly>  <includeDebugInformation>true</includeDebugInformation>  <referencedAssemblies>    <add name="system.dll" virtualPath="false" />    <add name="system.data.dll" virtualPath="false" />    <add name="system.web.dll" virtualPath="false" />    <add name="bin/BusinessEntities.dll" virtualPath="true" />    <add name="bin/CommonInterfaces.dll" virtualPath="true" />    <add name="bin/Exceptions.dll" virtualPath="true" />    <add name="bin/ExceptionHandling.dll" virtualPath="true" />    <add name="bin/Microsoft.ApplicationBlocks.ExceptionManagement.dll" virtualPath="true" />  </referencedAssemblies>  <code>    <![CDATA[using System;using System.Text;using System.Data;using System.Reflection;using System.Configuration;using System.Collections;using System.Collections.Generic;using System.Web;using System.Web.Caching;namespace IIS.WebCore {  /// <summary>  /// Razred za branje podatkov.  /// </summary>  public class DataBridge {    private static Cache cache = HttpContext.Current != null ? HttpContext.Current.Cache : null;      public DataBridge() { }    /// <summary>    /// Vrne šifrant vrednost (zalogo) za podano PI polje.    /// </summary>    /// <param name="_sProfile">Profil.</param>    /// <param name="_sPIIndex">PI index.</param>    /// <param name="_sFieldName">Ime PI polja.</param>    /// <param name="_sFilterFields">Morebitna filter PI polja loÄŤena z ';'.</param>    /// <param name="_sFilterValues">Vrednosti morebitnih PI polj loÄŤene z ';'.</param>    /// <returns>Seznam.</returns>    public IEnumerable GetPIValues(string _sPIIndex, string _sFieldName, string _sFilterFields, string _sFilterValues) {      object[] oArgs = new object[] { Settings.AppServerProfile, _sPIIndex, _sFieldName, _sFilterFields, _sFilterValues };      IEnumerable data = null;      // ali za te argumente Ĺľe obstaja cache vrednost      StringBuilder sb = new StringBuilder();      for (int ii = 0; ii < oArgs.Length; ii++) {        sb.Append(oArgs[ii]);      }      string sHash = Hash.GetHash(sb.ToString(), HashType.MD5);      if (cache != null && cache[sHash] != null) {        data = cache[sHash] as IEnumerable;      } else {        data = CommonHelper.InvokeRemoteMethod("GetPIValues", oArgs) as IEnumerable;        if (cache != null) {          cache.Insert(sHash, data, null, DateTime.Now.AddHours(24d), Cache.NoSlidingExpiration);        }      }      return data;    }     ]]>  </code></runtimeCode>....Izsek kode, ki prevede zadevo v zbir (assemlby) - uporaba CodeDOM prevajalnika:using System;using System.IO;using System.Web;using System.Data;using System.Configuration;using System.Collections;using System.Collections.Specialized;using System.Reflection;using System.CodeDom.Compiler;public class DnyCompiler { private volatile static object syncRoot = new Object(); /// <summary>    /// Prevede programsko kodo.    /// </summary>    public static void Compile() {      lock (syncRoot) {        CompilerParameters cparams = null;        ...        try {          ...          // branje & členitev XML datoteke          ...          string sCodeToCompile = ....;                     cparams = new CompilerParameters();          cparams.TempFiles = new TempFileCollection(AppDomain.CurrentDomain.SetupInformation.CachePath, false);          cparams.OutputAssembly = ...;          cparams.GenerateExecutable = false;          cparams.GenerateInMemory = false;          cparams.IncludeDebugInformation = bDebug;          // ref. zbiri          for (int ii = 0; ii < dtRefAssemblies.Rows.Count; ii++) {            cparams.ReferencedAssemblies.Add(....);          }          // referenca na trenutni zbir, ki se izvaja          cparams.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);         // prevajanje v zbir         CodeDomProvider provider = new CSharpCodeProvider();           CompilerResults = provider.CompileAssemblyFromSource(cparams, sCodeToCompile);         if (cresults.Errors.HasErrors) {            StringBuilder error = new StringBuilder();            foreach (CompilerError err in cresults.Errors) {              error.AppendFormat("{0}\n", err.ErrorText);            }            throw new ApplicationException(string.Format("Napaka pri prevajanju: {0}.", error.ToString()));         }    ....        }    }}..Prevedena koda (zbir), oz. nova funkcionalnost, je na voljo brez ponovnega grajenja (build) rešitve - primer uporabe klica metode v aspx datoteki:...<asp:objectdatasource runat="server" id="DS_Values" selectmethod="GetPIValues" typename="IIS.WebCore.DataBridge, RuntimeCode">  <selectparameters>    <asp:parameter name="_sPIIndex" type="String" defaultvalue="PI_Core" />    <asp:parameter name="_sFieldName" type="String" defaultvalue="Classification" />    <asp:parameter name="_sFilterFields" type="String" defaultvalue="" />    <asp:parameter name="_sFilterValues" type="String" defaultvalue="" />  </selectparameters></asp:objectdatasource>..Na ta način je precej olajšano dodajanje nove funkcionalnosti. Seveda pa obstajajo še drugi načini (VSA scripting,..).Lp, Damjan 

damjank
damjank - četrtek, 19. oktober 2006

Sem imel pred časom podoben problem - dinamično prevajanje c# kode iz datoteke XML (naknadno dodajanje funkcionalnosti brez novega grajenja z VS.NET) in nalaganje zbira v trenutno aplikacijsko domeno.Sistem ob zagonu preveri XML datoteko, če je njeno stanje od prejšnjega zagona spremenjeno, se izvede dinamično prevajanje kode.Npr. datoteka XML s programsko kodo za dinamično prevajanje:<?xml version="1.0" encoding="utf-8" ?><runtimeCode>  <outputAssembly>bin/RuntimeCode.dll</outputAssembly>  <includeDebugInformation>true</includeDebugInformation>  <referencedAssemblies>    <add name="system.dll" virtualPath="false" />    <add name="system.data.dll" virtualPath="false" />    <add name="system.web.dll" virtualPath="false" />    <add name="bin/BusinessEntities.dll" virtualPath="true" />    <add name="bin/CommonInterfaces.dll" virtualPath="true" />    <add name="bin/Exceptions.dll" virtualPath="true" />    <add name="bin/ExceptionHandling.dll" virtualPath="true" />    <add name="bin/Microsoft.ApplicationBlocks.ExceptionManagement.dll" virtualPath="true" />  </referencedAssemblies>  <code>    <![CDATA[using System;using System.Text;using System.Data;using System.Reflection;using System.Configuration;using System.Collections;using System.Collections.Generic;using System.Web;using System.Web.Caching;namespace IIS.WebCore {  /// <summary>  /// Razred za branje podatkov.  /// </summary>  public class DataBridge {    private static Cache cache = HttpContext.Current != null ? HttpContext.Current.Cache : null;      public DataBridge() { }    /// <summary>    /// Vrne šifrant vrednost (zalogo) za podano PI polje.    /// </summary>    /// <param name="_sProfile">Profil.</param>    /// <param name="_sPIIndex">PI index.</param>    /// <param name="_sFieldName">Ime PI polja.</param>    /// <param name="_sFilterFields">Morebitna filter PI polja loÄŤena z ';'.</param>    /// <param name="_sFilterValues">Vrednosti morebitnih PI polj loÄŤene z ';'.</param>    /// <returns>Seznam.</returns>    public IEnumerable GetPIValues(string _sPIIndex, string _sFieldName, string _sFilterFields, string _sFilterValues) {      object[] oArgs = new object[] { Settings.AppServerProfile, _sPIIndex, _sFieldName, _sFilterFields, _sFilterValues };      IEnumerable data = null;      // ali za te argumente Ĺľe obstaja cache vrednost      StringBuilder sb = new StringBuilder();      for (int ii = 0; ii < oArgs.Length; ii++) {        sb.Append(oArgs[ii]);      }      string sHash = Hash.GetHash(sb.ToString(), HashType.MD5);      if (cache != null && cache[sHash] != null) {        data = cache[sHash] as IEnumerable;      } else {        data = CommonHelper.InvokeRemoteMethod("GetPIValues", oArgs) as IEnumerable;        if (cache != null) {          cache.Insert(sHash, data, null, DateTime.Now.AddHours(24d), Cache.NoSlidingExpiration);        }      }      return data;    }     ]]>  </code></runtimeCode>....Izsek kode, ki prevede zadevo v zbir (assemlby) - uporaba CodeDOM prevajalnika:using System;using System.IO;using System.Web;using System.Data;using System.Configuration;using System.Collections;using System.Collections.Specialized;using System.Reflection;using System.CodeDom.Compiler;public class DnyCompiler { private volatile static object syncRoot = new Object(); /// <summary>    /// Prevede programsko kodo.    /// </summary>    public static void Compile() {      lock (syncRoot) {        CompilerParameters cparams = null;        ...        try {          ...          // branje & členitev XML datoteke          ...          string sCodeToCompile = ....;                     cparams = new CompilerParameters();          cparams.TempFiles = new TempFileCollection(AppDomain.CurrentDomain.SetupInformation.CachePath, false);          cparams.OutputAssembly = ...;          cparams.GenerateExecutable = false;          cparams.GenerateInMemory = false;          cparams.IncludeDebugInformation = bDebug;          // ref. zbiri          for (int ii = 0; ii < dtRefAssemblies.Rows.Count; ii++) {            cparams.ReferencedAssemblies.Add(....);          }          // referenca na trenutni zbir, ki se izvaja          cparams.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);         // prevajanje v zbir         CodeDomProvider provider = new CSharpCodeProvider();           CompilerResults = provider.CompileAssemblyFromSource(cparams, sCodeToCompile);         if (cresults.Errors.HasErrors) {            StringBuilder error = new StringBuilder();            foreach (CompilerError err in cresults.Errors) {              error.AppendFormat("{0}\n", err.ErrorText);            }            throw new ApplicationException(string.Format("Napaka pri prevajanju: {0}.", error.ToString()));         }    ....        }    }}..Prevedena koda (zbir), oz. nova funkcionalnost, je na voljo brez ponovnega grajenja (build) rešitve - primer uporabe klica metode v aspx datoteki:...<asp:objectdatasource runat="server" id="DS_Values" selectmethod="GetPIValues" typename="IIS.WebCore.DataBridge, RuntimeCode">  <selectparameters>    <asp:parameter name="_sPIIndex" type="String" defaultvalue="PI_Core" />    <asp:parameter name="_sFieldName" type="String" defaultvalue="Classification" />    <asp:parameter name="_sFilterFields" type="String" defaultvalue="" />    <asp:parameter name="_sFilterValues" type="String" defaultvalue="" />  </selectparameters></asp:objectdatasource>..Na ta način je precej olajšano dodajanje nove funkcionalnosti. Seveda pa obstajajo še drugi načini (VSA scripting,..).Lp, Damjan 

MihaM
MihaM - sobota, 16. september 2006

Seveda, najlažje je prevest v zbir (assembly).Mogoče si poglej tole povezavo: http://www.codeproject.com/csharp/cs-script_for_cp.asp