2009-06-11 9 views
2

.Net에서 코드를 반사적으로 또는 동적으로 어떻게 실행합니까? 는 XML이 안에 뭔가가 포함 된 경우 '[]'난 안 텍스트로하지만 코드로 텍스트를 처리 할 :.Net에서 코드를 반사적으로 실행

<Name>DateZero</Name>
<Value>DateTime.Now.AddDays(-2)</Value>

<Name>DateOne</Name>
<Value>[DateTime.Now.AddDays(-1).ToString("MM/dd/yy")]</Value>

<Name>DateTwo</Name>
<Value>[DateTime.Now.ToString("MM/dd/yy")]</Value>

DateZero의 값이 (DateTime.Now.AddDays "로 렌더링하는 것을 의미 -2) "로 표시되지만 다음 2 개의 경우 06/10/09 및 06/11/09로 렌더링됩니다.

+0

정말 모든 C# 코드를 허용하고 싶습니까? 큰 보안 구멍처럼 보입니다. – Cheeso

+0

인트라넷입니다. – JonathanWolfson

+0

답변을 찾고 있는데 참조도 아니고 제안도 아닙니다. – JonathanWolfson

답변

2

CS-Script 당신이 찾고있는 것을 할 수 있습니다. 그 예 중 하나에서

:

당신이 원하는 것을 할 정도로 쉬워야한다
Assembly assembly = CSScript.LoadMethod(
     @"public static void PrintSum(int a, int b) 
      { 
       Console.WriteLine((a+b)); 
      }"); 

AsmHelper script = new AsmHelper(assembly); 
script.Invoke("*.PrintSum", 1, 2); 

. 나는 우리 규칙 엔진을 위해 그것을 사용하고있다. (그냥 Boo에서 바꾼다.) 동적 코드를 위해 좋다.

1

나는 당신의 접근 방식을 전혀 추천하지 않지만, Reflection.Emit을 사용하여 원하는 것을 할 수 있습니다. 여기에 a tutorial입니다.

1

'가능한'상수 집합을 정의하여 코드에서 파싱하고 전달할 C# 비트가 아닌 동적으로 실행하는 것이 더 좋지 않겠습니까?

2

기본 규칙 프로세서가 필요합니다. 필요한 것을 성취하기위한 몇 가지 옵션이 있습니다. 앞서 언급 한 Randolpho와 마찬가지로 런타임시 Lightweight IL 코드를 생성하기 위해 Reflection.Emit을 사용할 수 있습니다. 또 다른 대안은 .NET 3.5를 사용하는 경우 Expression Tree를 사용하는 것입니다.

LINQ가 도입됨에 따라 Microsoft는 컴파일하는 동안 LINQ 문을 번역 할 수있는 .NET에 기본 식 엔진을 추가해야했습니다. 표현 라이브러리는 LINQ를 지원하는 것에 국한되지 않으며, XML을 표현식 트리로 바꾸는 기본 파서를 작성할 수 있어야합니다. 각 표현식 트리는 나중에 동기식 또는 비동기식으로 호출 될 수있는 대리자로 컴파일 될 수 있습니다.

당신은 식 트리 경로를 탐색 할 때 유용는 아래의 링크를 찾을 수 있습니다

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

그것은 동적 표현 파서를 제공하는, 그것은 완전히 당신이 가지고있는 표현식을 지원하지 않는 동안 귀하의 질문은 거의 모든 다른 기본 표현을 지원합니다.

1

정말로 C#을 허용 하시겠습니까?
그렇다면 this script engine for C#을보고 싶을 수 있습니다. 임의의 코드를 실행할 수 있다는 것은 큰 보안 노출입니다.

.NET 4.0 (베타 버전, 지금 출시 예정)을 기다리는 것이 좋습니다.이 경우 DLR 또는 동적 언어 런타임을 활용할 수 있습니다.

반면에 .NET 4.0에 의존하고 싶지 않고 자신을 제한하고 싶다면 Reflection을 매우 간단하게 사용할 수 있습니다. 예를 들어 DateTime 인스턴스의 메서드에 자신을 한정시킬 수 있다면 더 간단해질 것입니다. 이 예제에서는 NOW로 설정된 DateTime 인스턴스에서 리플렉션을 통해 메서드를 호출하는 방법을 보여줍니다.

DateTime d = DateTime.Now; 
    string logicToInvoke= "Now.AddDays(12)"; 
    string pattern = @"^Now\.(?<methodname>\w+)\((?<argstring>[^\)]*)\)"; 
    RGX.Match match = RGX.Regex.Match(logicToInvoke, pattern); 

    // If match not found, logic is improperly formed. 
    if (!match.Success) 
    { 
     Console.WriteLine("The DateTime method logic is improperly formed."); 
     return; 
    } 

    // Store method and arg 
    string methodName = (string) match.Groups["methodname"].Value; 
    string argString = (string) match.Groups["argstring"].Value; 

    Console.WriteLine("Invoking method '{0}' with args '{1}'...", methodName, argString); 
    System.Type t= d.GetType(); 

    try 
    { 
     switch (methodName) 
     { 

     case "AddDays" : 
      int daysToAdd = System.Int32.Parse(argString); 
      DateTime result = (DateTime) t.InvokeMember (methodName, 
              System.Reflection.BindingFlags.Public | 
              System.Reflection.BindingFlags.Instance | 
              System.Reflection.BindingFlags.InvokeMethod , 
              null, d, new object [] {daysToAdd}); 

      Console.WriteLine("Result: {0}", result.ToString("yyyy/MM/dd")); 
      break; 
     default: 
      Console.WriteLine("unsupported method: {0}", methodName); 
      break; 
     } 

    } 
    catch (System.Exception exc1) 
    { 
     Console.WriteLine("Exception while invoking method: {0}", exc1); 
    } 

DateTime 값의 형식을 그 값과 별도로 유지하는 것이 좋습니다. 시간 ("YY/MM은/DD")의 형식은 더 나은와 마찬가지로 속성에 지정 될 수 있습니다

<Name>DateOne</Name> 
<Value format="MM/dd/yy">[Now.AddDays(-1)]</Value> 
0

후, 생성하고 메모리에 당신의 코드와 클래스를 컴파일하는 첫번째 필요 그것은 당신이 그것에 대해 반성하고 동적 코드가 살아있는 메소드를 호출 할 필요가 있기 때문에 컴파일되었고, 메소드는 또한 값을 반환 할 수있었습니다.여기

당신은 당신이해야 할 노력하고 정확하게에 따라

0

Dynamic Code을 시작하는 링크입니다, 당신은 Spring .NET에서 일부 구성 요소가 유용 할 수있다. Spring .NET Expressions을보십시오. 예를 들어

: 마지막 쉼표, 가장 쉬운에 C#을 구문이 필요하지 않은 경우

(DateTime) ExpressionEvaluator.GetValue(null, "new DateTime(1974, 8, 24)")

"새로운 날짜 시간 (1974,8,24)는"텍스트

0

입니다 이 작업을 수행하는 방법은 아마 IronPython과 같은 DLR 언어를 사용하는 것입니다. "호스팅 ironpython"에 대한 Google 및 샘플을 찾을 수 있습니다.

관련 문제