I ran this https://stackoverflow.com> I can find his closest thing, but not quite.
Let me explain what my final goal is before my question, I create a compiler platform that includes a web interface, because of this I want to do everything in memory (not create files), so I want to be able to compile the code, and then be able to refer to objects in the class that I just compiled for arbitrary testing. I know how this sounds unsafe, so security contributions are welcome.
My question is: how to compile a C # source into memory and instantiate this class?
I am currently at the stage where I can generate a valid .dll and import it and use it inside VisualStudio manually.
My next 2 steps:
- load assembly automatically (this is what i ask here)
- This would mean that I no longer need to specify the path to the dll and get the address of the private members of the class manually
- arbitrarily refer to its members
- This means that I can create an interface for a class without knowing its predecessors, such as how the foreach loop works with pairs of key values.
To do this completely in memory, I tried this. (source then explanation)
private object sourceToObj(string source) { string source = "..."; CSharpCodeProvider pro = new CSharpCodeProvider(); CompilerParameters params = new CompilerParameters(); params.GenerateInMemory = true; params.GenerateExecutable = false; params.ReferencedAssemblies.Add("System.dll"); CompilerResults res = pro.CompileAssemblyFromSource( params, source ); Assembly DOTasm = res.CompiledAssembly; AppDomain domain = AppDomain.CreateDomain( "thisdomain" ); domain.load( DOTasm , ); domain.CreateInstanceAndUnwrap( DOTasm .FullName, ); return ; }
Finally, as this point in the code, I hope to return some kind of object, I can name the property. Therefore, the call object obj = new sourceToObj(source).class(); or something will be possible.
Walking down this path, which may be wrong, leaves me with three unknowns.
- What is a
System.Security.Policy.Evidence assemblySecurity object. - What is the correct parameter for
AppDomain.CreateInstanceAndUnwrap() - How can I return this as an object?
Of course, this method may be wrong, it is based on a link above which is close, but there is no turkey.
Edit: after more research, I wanted to include a sample source file.
namespace testNS { public partial class i18Rule { private string i18_Name; private string i18_Value; public void setName(string s) { i18_name = s; } }; };
I believe that I have made some progress and moved to the second sentence of my question, how to create an instance of this file.
I went ahead and used AppDomain to contain my build. I also went the way of writing to disk and read it into a byte array, as it was done in this question, I happened after Compile C # on the fly .
private void sourceToUnitTest(string source, callBack CB) { var pro = new CSharpCodeProvider(); var DOMref = AppDomain.CurrentDomain.GetAssemblies() .Where(obj => !obj.IsDynamic) .Select(obj => obj.Location) .ToArray(); var Cparams = new CompilerParameters( DOMref ); Cparams.OutputAssembly = "SOURCE.DLL"; CompilerResults res = pro.CompileAssemblyFromSource(Cparams, source); Assembly asm = res.CompiledAssembly; Type[] allTypes = res.CompiledAssembly.GetTypes(); foreach (Type t in allTypes) { TryLoadCompiledType(res, t.ToString()); Debug.WriteLine(t.ToString()); } }