Blog Stats
  • Posts - 99
  • Articles - 5
  • Comments - 236
  • Trackbacks - 105

 

Dependent in memory assemblies

Another GREAT question in MS newsgroups today.


I'm using the CSharpCodeProvider to buils some assemblies @ runtime which are
never saved as files (cp.GenerateInMemory = true;).
The generated assemblies are hierachically dependent on each other so I
generate the "bottom" assemblies first.

How do I add a dependency to another previously loaded (generated) assembly?

I would be happy if CompilerParameters.ReferencedAssemblies.Add could take a
System.Reflection.Assembly reference as parameter.

A possible solution would be to generate dll files and reference them but I
like the idea of not having any files to cleanup when my application exits.


I have seen this one a few times before but googling this subject brings up nothing so I will give a quick write up on it.

Often times when generating code for runtime use the assembly is simply created in memory. This prevents us from having to write out a temporary file for the assembly. Since the assembly is intended to have the same lifespan as our appdomain and the assembly is loaded into memory anyways, there is little use in us writing it to a temporary file as well.

A common issue that people run into is that it is rare that the assembly is completely stand-alone. It often times has to reference other assemblies. This is quite straight forward when you are dealing with assemblies that are on disk, just add the assembly as follows

Parameters.ReferencedAssemblies.Add("System.dll");

Sometimes however we want our assembly to reference another dynamically generated assembly. In this case many resort to writing the dependency out to disk as a temp file then reference the disk based tempory assembly when they generate the main assembly. This does not need to be done, all we need to do is assign an OutputAssembly to our first assembly and it will be loaded into our appdomain as that name. As such when the main assembly is loaded it will be seen that the assembly is in fact already in memory and as such accessible.

This method does not always work though. If the assembly that you are generating is to be hosted in another app domain (lets say it is its own process, take the example and make the example generate an executable for the main assembly that it then tries to run). The in memory assembly will only be within the calling appdomain and as such will not be accessible to the new appdomain.

In the sample code two assemblies are generated. The satellite assembly which contains a single class OtherObject that has a static method SomeMethod and the main assembly which a class MainObject with a method Test that calls into OtherObject from the other assembly. You will notice the two key points of the code are in

GenerateSatelliteAssembly : Parameters.OutputAssembly = "inmemoryassembly.dll"
GenerateMainAssembly : Parameters.ReferencedAssemblies.Add("inmemoryassembly.dll");

That said ... Here's the code!


using System;
using System.Reflection;
using System.CodeDom.Compiler;

using Microsoft.CSharp;
namespace TestInMemoryAssemblies
{
 class MainEntryPoint {
  private static void CheckResults(CompilerResults Results) {
   if(Results.Errors.Count > 0) {
    throw new System.Exception("Compile Failed");
   }
  }

  static Assembly GenerateMainAssembly() {
   Microsoft.CSharp.CSharpCodeProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
   ICodeCompiler compiler = codeProvider.CreateCompiler();
   CompilerParameters Parameters = new CompilerParameters(new string[] {"mscorlib.dll"});
   Parameters.ReferencedAssemblies.Add("System.dll");
   Parameters.ReferencedAssemblies.Add("inmemoryassembly.dll");
   Parameters.GenerateExecutable = false;
   Parameters.GenerateInMemory = true;
   string source = "";
   source += "public class MainObject {";
   source += " public void Test() {";
   source += "     System.Console.WriteLine(\"Running in main assembly, calling satellite assembly\");";
   source += "     OtherObject.SomeMethod();";
   source += "     System.Console.ReadLine();";
   source += " }";
   source += "}";
   CompilerResults results = compiler.CompileAssemblyFromSource(Parameters, source);
   CheckResults(results);
   return results.CompiledAssembly;
  }

  static void GenerateSatelliteAssembly() {
   CSharpCodeProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
   ICodeCompiler compiler = codeProvider.CreateCompiler();
   CompilerParameters Parameters = new CompilerParameters(new string[] {"mscorlib.dll"});
   Parameters.ReferencedAssemblies.Add("System.dll");
   Parameters.OutputAssembly = "inmemoryassembly.dll";
   Parameters.GenerateExecutable = false;
   Parameters.GenerateInMemory = true;
   string source = "";
   source += "public class OtherObject {";
   source += " public static void SomeMethod() {";
   source += "     System.Console.WriteLine(\"Hello World from other object located in an in memory assembly\");";
   source += " }";
   source += "}";

   CompilerResults results = compiler.CompileAssemblyFromSource(Parameters, source);
   CheckResults(results);
  }
  static void Main(string[] args) {
   //build the satellite assembly
   GenerateSatelliteAssembly();
   //build the main assembly
   Assembly Generated = GenerateMainAssembly();
   //Get the main object
   object o = Generated.CreateInstance("MainObject");
   //Get the type of the main object
   Type t = o.GetType();
   //Request the Test method from the type
   MethodInfo mi = t.GetMethod("Test");
   //call the test method
   mi.Invoke(o, null);
  }
 }
}


*UPDATE*

This only gives the appearance of working properly. This will in fact load the satellite assembly into the appdomain twice.

'ConsoleApplication6.vshost.exe' (Managed): Loaded 'C:\Documents and Settings\Greg Young\My Documents\Visual Studio 2005\Projects\ConsoleApplication6\ConsoleApplication6\bin\Debug\ConsoleApplication6.exe', Symbols loaded.
'ConsoleApplication6.vshost.exe' (Managed): Loaded 'inmemoryassembly', No symbols loaded.
'ConsoleApplication6.vshost.exe' (Managed): Loaded 'wessmgnq', No symbols loaded.
'ConsoleApplication6.vshost.exe' (Managed): Loaded 'C:\Documents and Settings\Greg Young\My Documents\Visual Studio 2005\Projects\ConsoleApplication6\ConsoleApplication6\bin\Debug\inmemoryassembly.dll', No symbols loaded.

The reason that this happens appears to be some oddities with the CSharpCompiler. From poking through some reflectored code it appears that the CSharpCompiler always writes out files and the lifespan of these files is what is controlled by the “in memory” flag. It further appears that by giving an assembly a name you force it to be treated as a normal assembly at some points and an in-mmeory assembly at others as opposed to a normal inmemory assembly :( I probably should have figured out this from the fact that it didn't work with the automagically generated names but the final decision on this is that there is no way to do this.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Feedback

# re: Dependant in memory assemblies

Gravatar Hi Greg,

Thanks alot for your answer on the dotnet.languages.csharp newsgroup.

If I don't give the assemblies filenames they're given names by the compiler. Wouldn't it also be possible to get that name from the compiled assembly and use that for the dependency?

/Jan 4/27/2006 4:01 AM | Jan

# re: Dependant in memory assemblies

Gravatar I tried it and it didn't work :(

4/27/2006 4:09 AM | Greg Young

# re: Dependent in memory assemblies

Gravatar Thank you very much for this info!

I would have never thought that setting the OutputAssembly property was of any use, when the compiler generated doesn't work...

Moritz 9/8/2006 5:46 AM | Moritz

# re: Dependent in memory assemblies

Gravatar Useful information. Thanks. 9/29/2008 9:06 AM | Alphakanal

# London escorts

Gravatar It is rather interesting for me to read this blog. Thank author for it. I like such topics and everything connected to this matter. I definitely want to read more on that blog soon. 11/21/2009 2:16 AM | Russian escorts

# Best shop ever

Gravatar Keep on posting such themes. I love to read stories like this. Just add more pics :) 1/22/2010 6:43 PM | SteaveTheMighty

# re: Dependent in memory assemblies

Gravatar I am always happy with the amount of info I find to elp me with my programing and this is no exception thank you so much, 1/29/2010 5:43 AM | Escorts in London

# Great post

Gravatar Interesting story you got here. It would be great to read something more about that matter. Thanks for posting that information. 2/11/2010 11:05 AM | PhillDoc

# re: Dependent in memory assemblies

Gravatar A dependant assembly is resolved when a type is needed that is defined in that assembly. So the assembly is loaded on demand.The CLR loader loads and initializes as little as it can get away with 4/10/2010 1:18 AM | giochi dei casinò online

# re: Dependent in memory assemblies

Gravatar Great info for Geeks you done it again thank you so much!!! 6/2/2010 4:31 AM | Escorts in London

# re: Dependent in memory assemblies

Gravatar I got really stuck on this code so I am glad that someone finally figured it out! 6/7/2010 6:49 AM | London Escorts

# re: Dependent in memory assemblies

Gravatar thanks so much foryour help. 8/5/2010 7:41 PM | australian escort

# re: Dependent in memory assemblies

Gravatar I appreciate your input. will read again. 8/6/2010 1:23 PM | dubai escort

# re: Dependent in memory assemblies

Gravatar this is well worth another read. thank you 8/10/2010 7:42 PM | delhi escorts

# re: Dependent in memory assemblies

Gravatar Often times when generating code for runtime use the assembly is simply created in memory. 8/11/2010 1:36 PM | sydney escort

# re: Dependent in memory assemblies

Gravatar thankyou for the help for my programming, there is alot of great help on the internet but this has helped the most thankyou. 9/6/2010 8:52 AM | london escorts

# re: Dependent in memory assemblies

Gravatar Intresting aricles you place here.
It would be useful to read anything more concerning this topic.
Thnx for tell that information.
With best regards Angela!!
9/16/2010 8:06 AM | Kiev escort

# re: Dependent in memory assemblies

Gravatar this doesn't work. when i set output assembly it generates a dll even if generateexecuteable = false. generateexecutable just means that the dll has an entry point(sub main) 10/2/2010 12:39 PM | asdfsdf

# re: Dependent in memory assemblies

Gravatar nevermind my last comment
apparently you have to set Parameters.GenerateInMemory = True
AFTER!! you set output assembly 10/2/2010 12:41 PM | asdfasdf

# re: Dependent in memory assemblies

Gravatar The Assemblies Website aims to provide high-quality, instant access primary and secondary school assemblies for teachers and others leading collective worship. 10/6/2010 12:59 AM | Huntsville OB GYN

# re: Dependent in memory assemblies

Gravatar Intresting aricles you public here.
It will be useful to read anything more concerning this topic.
Thank for giving that information.
With best regards!
10/6/2010 6:18 AM | Kiev escort

# re: Dependent in memory assemblies

Gravatar The Election Commission of India (ECI) has announced the schedule for by-elections in the legislative assemblies of Uttar Pradesh, Assam, Himachal Pradesh, Kerala, Rajasthan, Chattisgarh, and West Bengal and in the House of People from 20 - Firozabad P.C of Uttar Pradesh to fill the vacant seats. 10/6/2010 8:10 AM | Huntsville OB GYN

# re: Dependent in memory assemblies

Gravatar interesting approach, thank you! 10/7/2010 3:07 PM | tantric massage london

# re: Dependent in memory assemblies

Gravatar thankyou for the help for my programming 10/15/2010 2:54 PM | lpg conversion

# re: Dependent in memory assemblies

Gravatar Stock market India is volatile and all those who speculate in market are loosing everyday. Please remember stock market is not for speculation purpose. If one feel investing in stock market is gamble then its better to think again.
One should always note that if they want to invest money they should do proper research be it fundamental research or technical research. Just think how come you can invest
your money without any convincing reason for the same?
Indian stock market is one of the most happening and emerging market. Major Indian stock exchanges are BSE and NSE and both are of world class standards.
So grab good stocks and invest that’s the bottom line.
We hope to see you in major profits.


Intraday Tips 10/18/2010 1:26 AM | Commodity Tips

# re: Dependent in memory assemblies

Gravatar Useful information. 10/19/2010 9:00 AM | lpg conversion

# re: Dependent in memory assemblies

Gravatar Thanks for the great share. 10/26/2010 11:09 AM | diecast cars

# re: Dependent in memory assemblies

Gravatar Paris thanks you with all of its heart 11/30/2010 2:42 PM | happy

# re: Dependent in memory assemblies

Gravatar Paris thanks you with all of its heart you know 11/30/2010 2:43 PM | annaferrini

# re: Dependent in memory assemblies

Gravatar I appreciate your input. will read again. 12/1/2010 4:28 AM | London Escort

# re: Dependent in memory assemblies

Gravatar C# is not anymore a viable solution nowadays but I really appreciate you're sharing with us all these, thanks a lot! 12/6/2010 11:05 AM | Protein Powders

# re: Dependent in memory assemblies

Gravatar Thanks for the effort you have put on your blog I really like your post . Keep on posting !!! 12/8/2010 5:03 AM | RGGALAK

# re: Dependent in memory assemblies

Gravatar Great insight and very uplifting 2/8/2011 4:28 AM | Paris escort

# re: Dependent in memory assemblies

Gravatar When the current application looks for assemblies, it looks in several locations (bin folder, gac, etc..) if it can not find one, then the developer needs to manually tell the application where to look. You can do this by intercepting the AssemblyResolve event, and using the event args to tell the CLR where your assembly is.

Thank you,
Intraday Trading Tips || Trading Tips 2/15/2011 1:39 AM | Intraday Tips

# re: Dependent in memory assemblies

Gravatar This does not need to be done, all we need to do is assign an OutputAssembly to our first assembly and it will be loaded into our appdomain as that name. 2/17/2011 10:08 AM | Watches

# eatcity

Gravatar Great topic, please keep it up... 3/9/2011 8:21 AM | Brazilian Escorts

# re: Dependent in memory assemblies

Gravatar London escort agency which provides genuine female escort models in Central London area. 3/30/2011 9:19 AM | escorts london

# re: Dependent in memory assemblies

Gravatar Great question and a very good answer, thank you 3/30/2011 9:40 AM | LPG Suppliers

# re: Dependent in memory assemblies

Gravatar If you are looking for European escorts Bestescort4U is the best place in London 4/1/2011 3:22 AM | London escorts

# re: Dependent in memory assemblies

Gravatar Bentley's International Models is a London escort agency providing elite top class 4/3/2011 5:45 AM | Elite London escorts

# re: Dependent in memory assemblies

Gravatar Asian Classic is a highly rated London escorts service in Central London 4/3/2011 10:03 AM | Asian London escorts

# re: Dependent in memory assemblies

Gravatar Elite Club International is very selective and work only with ladies who really can provide an excellent escort service experience. 4/3/2011 4:03 PM | Elite escorts

# re: Dependent in memory assemblies

Gravatar Bunny Planet is an Exclusive Online Gentlemen's Club filled with Adult Stars, Adult Entertainers, Centerfolds and Erotic Models who want to meet you in person now! 4/6/2011 2:40 PM | Porn Star Escorts

# re: Dependent in memory assemblies

Gravatar We provide honest, discreet, confidential UK and worldwide high class escorts services for gentlemen of taste who interested in elegant and sexy companionship. 4/8/2011 6:28 AM | London escort agency

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

 

 

Copyright © Greg Young