.net、コードの動的実行
public static Assembly Compile(string src) { var snip = new CodeSnippetCompileUnit(src); var codedom_option=new Dictionary<string, string>(); codedom_option.Add("CompilerVersion", "v3.5"); using (var provider = new Microsoft.CSharp.CSharpCodeProvider(codedom_option)) { var param = new System.CodeDom.Compiler.CompilerParameters(); param.GenerateInMemory = true; param.TreatWarningsAsErrors = true; param.ReferencedAssemblies.Add("System.Web.dll"); //参照の追加 var result = provider.CompileAssemblyFromSource(param, src); if (result.Errors.HasErrors || result.Errors.HasWarnings) throw new CompileErrorException(result.Errors,src); //まあ適当に return result.CompiledAssembly; } }
これで渡したコードをコンパイルしてAssemblyにできる。
デフォだとC#3.0のコードがコンパイルエラー、CSharpCodeProviderのコンストラクタでコンパイラバージョンを明示的に指定したらいけた。
MSDNにはたとえば "3.5"
とか書いてあるけどtypo、"v3.5"じゃないとcsc.exeがないエラーになる。
渡すコードは断片(例えば"1+1")ではなく完全なものが必要。
コードを実行する際はAssemblyのGetType(string name)メソッドを実行してTypeを入手、インスタンス作るなり静的メソッド呼ぶなり。
Assemblyがどういう位置づけなのかよくわからないのだけど、同じnamespace、同じ名前の型を含むソースを複数回コンパイルしても問題なく実行できる(型は上書きされない)。
ちなみに一度コンパイルしたコードをメモリ上からアンロードする方法は不明、AppDomainがらみの何かをする必要があるようだが。