2012-04-02 6 views
1
내 응용 프로그램에 일부 특정 모듈 functonality를 추가하려고

에서 클래스를 액세스, 내가 그들을 런타임에 프로그램으로 가져온 후 자신의 클래스를 생성 할 수 있도록 사용자가 필요, 이러한 클래스는 특정을 따릅니다 템플릿을 사용하여 새 클래스에서 함수를 호출 할 수 있습니다.이 컴파일 및 실행

예를 들어, 클래스가 될 수 : http://pastebin.com/90NTjia9

내가 클래스를 컴파일 한 후) (해봐요을 실행하는 것입니다;

어떻게 C#에서이를 것? 사용자가 (그들은 정말들이 C#을 클래스를 작성하는 경우이 있어야 비주얼 스튜디오 등) 필요한 도구가있는 경우

+1

일반적으로 응용 프로그램에 후크를 제공하는 dll을 사용자에게 제공하여이 작업을 수행 할 수 있습니다. 이것은 그들이 당신의 앱이로드 할 수있는 dll을 생성 할 수있게합니다. – mikerobi

+0

난 당신이 단순히 .cs 디렉토리에 파일을하고 컴파일하고 실행 드롭 수 있도록 프로그램을 사용했습니다. 여기 – JamieB

+1

참조 대린 디미트로프의 대답 : http://stackoverflow.com/questions/4718329/compiling-code-dynamically-using-c-sharp LINQPad 작동되는 방식을 확인할 수 있습니다 –

답변

4

, 그들은 당신이 동적으로로드 할 수 DLL, 당신을 제공 할 수

private static T CreateInstance(string assemblyName, string typeName) 
{ 
    var assembly = Assembly.LoadFrom(assemblyName); 

    if (assembly == null) 
     throw new InvalidOperationException(
      "The specified assembly '" + assemblyName + "' did not load."); 

    Type type = assembly.GetType(typeName); 
    if (type == null) 
     throw new InvalidOperationException(
      "The specified type '" + typeName + "' was not found in assembly '" + assemblyName + "'"); 

    return (T)Activator.CreateInstance(type); 
} 

당신이 유형의 인스턴스를 캐스팅하기 위해 abstractclass 또는 interface을 통과 할 수 있도록 T 일반적인 매개 변수가있다 :

public interface IDoSomething 
{ 
    bool DoSomething(); 
} 

사용자가 INH 이 허용

public class UserDefinedClass : IDoSomething 
{ 
    public bool DoSomething() 
    { 
     // Implementation here. 
    } 
} 

당신이 유형의 안전을 유지하고 오히려 그렇게하는 반사에 의존하지 않고 직접 클래스 메소드를 호출하는이 인터페이스에서 erit는 자신의 클래스를 쓸 때. 당신이 할 수있는 compile their class at runtime이 같은

당신이 정말로 사용자가 C#을 소스를 제공하려면

:

private Assembly BuildAssembly(string code) 
{ 
    var provider = new CSharpCodeProvider(); 
    var compiler = provider.CreateCompiler(); 
    var compilerparams = new CompilerParameters(); 
    compilerparams.GenerateExecutable = false; 
    compilerparams.GenerateInMemory = true; 
    var results = compiler.CompileAssemblyFromSource(compilerparams, code); 
    if (results.Errors.HasErrors) 
    { 
     var errors = new StringBuilder("Compiler Errors :\r\n"); 
     foreach (CompilerError error in results.Errors) 
     { 
      errors.AppendFormat("Line {0},{1}\t: {2}\n", 
        error.Line, error.Column, error.ErrorText); 
     } 
     throw new Exception(errors.ToString()); 
    } 
    else 
    { 
     return results.CompiledAssembly; 
    } 
} 

그런 다음, 당신은 대신 외부에서로드 된 어셈블리, 위의 CreateInstance 코드에서 결과 어셈블리를 대체합니다. 사용자는 여전히 해당 학급의 상단에 적절한 using 문을 제공해야합니다.

실제로 인터넷에서 완전한 설명이 필요없는 경우에 대비하여 how to get an Eval() function을 C#으로 설명하는 장소가 있습니다.

관련 문제