Referencing in-memory assembly on compile

A

Andrus

I need compile in-memory assembly which references to other in-memory
assembly.

Compiling second assembly fails with error

Line: 0 - Metadata file 'eed7li9m, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' could not be found

Saving assembly to Windows temp directory for referencing only creates huge
amout of temporary
files. I don't know any way to delete those files since they are locked by
loaded assemblies.
Creating separate Appdomain causes issues when I want to pass my
application types.

How to fix ?

Is is possible/reasonabe to compile assembly twice: one compile to memory
and second compile to temporary directory for reference only ?
Or is it possible to delete those temporary files ?

Andrus.


using System;
using System.CodeDom.Compiler;
using System.Windows.Forms;

class Program {
static void Main() {
Microsoft.CSharp.CSharpCodeProvider provider = new
Microsoft.CSharp.CSharpCodeProvider();

CompilerParameters compilerParameters = new CompilerParameters {
GenerateInMemory = true
};

CompilerResults compilerResults =
provider.CompileAssemblyFromSource(compilerParameters, "public
class Test {}");
if (compilerResults.Errors.HasErrors)
throw new ApplicationException("Unexpected compile error");

var asm1 = compilerResults.CompiledAssembly;

compilerParameters.ReferencedAssemblies.Add(asm1.FullName);

compilerResults =
provider.CompileAssemblyFromSource(compilerParameters, "public
class Test1 : Test {}");

if (compilerResults.Errors.HasErrors) {
string msg;
msg = compilerResults.Errors.Count.ToString() + " Errors:";
for (int x = 0; x < compilerResults.Errors.Count; x++)
msg = msg + "\r\nLine: " +
compilerResults.Errors[x].Line.ToString() + " - " +
compilerResults.Errors[x].ErrorText;

//Causes Line: 0 - Metadata file 'eed7li9m, Version=0.0.0.0,
Culture=neutral,
//PublicKeyToken=null' could not be found
MessageBox.Show(msg);
}
}
}
 
A

Andrus

Fernando,
You need to use reflection to read the public API of the assembly that you
want to reference, then generate code for skeleton for all the public
classes and it's members, also add an static initializer that takes in an
Assembly object reference and saves it to a static field. Then add two
fields, one of type System.Object called _instance, and one of type
System.Type called _instanceType to all your generated classes and on the
constructors use the static Assembly object's CreateInstance to create an
instance of the type on the referenced assembly and save it to the
_instanceField. Then use the GetTypes() method to get an array of the
types that the referenced assembly contains, iterate through it comparing
the .FullName property with the full name of the type you're referencing
and when you find it save it to the _instanceType field. Now on you
generated methods you can use the Invoke method of the _instanceType field
to call methods on your remote class. Then you need to add this generated
code to the code that you're trying to compile. Additionally you need to
add one more static initializer method to the code being compiled, it
should take in the Assembly object reference and pass it to the static
initializer of the generated code. Finally after you compile the assembly
and load it you must call the static initializer pass the "reference to
the referenced assembly" to it.

It's not as hard as it sounds since reflection will give you all the info
that you need to generate the code tree.

Thank you. This looks complicated for me.
Where to find generic code which implements this ?
Currently I implemented code which creates assemblies in windows temp
directory.
In next incovation my application clean temp directory from the assemblies
which are created during previous run.
Is this OK ?
Unfortunately MS Reportviewer control in local mode cannot still find any
dynamic assembly.

Andrus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top