Hi, > So, alternately, I would compile in a child AppDomain and write a > component to disassemble and port the assembly over to the parent > domain, reconstructing it as RunAndCollect there. These will be > relatively simple assemblies - just a bunch of properties representing > variables and simple methods conforming to a fixed delegate that do > formula calculations quickly. I'll just eat the 200 ms or so startup delay > for compilation, perhaps a worker thread during project load may help > here. I'll already have a crapload of disk access going on at that time, > we'll have to see.
You mean, in the child AppDomain, you would compile the assembly as a saveable assembly (AssemblyBuilderAccess.RunAndSave or AssemblyBuilderAccess.Save)? Okay, that's great - once you've got a file on disk, you can use Cecil to disassemble it. > I've read that Cecil can do things that Reflection.Emit can't, so my > next question is: Are there any particular APIs you'd point me > towards for reconstructing a simple class in this manner, or should > I be able to do it with Reflection.Emit alone? Cecil can do things that Reflection.Emit can't (e.g., modifying existing assemblies whereas Reflection.Emit can only create new ones), but it can't help you with producing in-memory (collectible) assemblies. For this, Reflection.Emit is the only way to go, and you probably won't run into any API restrictions with it. Regards, Fabian On Tue, Jul 10, 2012 at 1:28 AM, Dlux <[email protected]> wrote: > > Thanks. Yes, I did get Rosalyn functionality confused with some of the C# > 5.0/NET 4.5 functionality. Oh well. > > So, alternately, I would compile in a child AppDomain and write a component > to disassemble and port the assembly over to the parent domain, > reconstructing it as RunAndCollect there. These will be relatively simple > assemblies - just a bunch of properties representing variables and simple > methods conforming to a fixed delegate that do formula calculations quickly. > I'll just eat the 200 ms or so startup delay for compilation, perhaps a > worker thread during project load may help here. I'll already have a > crapload of disk access going on at that time, we'll have to see. > > I've read that Cecil can do things that Reflection.Emit can't, so my next > question is: Are there any particular APIs you'd point me towards for > reconstructing a simple class in this manner, or should I be able to do it > with Reflection.Emit alone? > > > On Wednesday, July 4, 2012 2:25:41 AM UTC-4, Fabian Schmied wrote: >> >> Hi, >> >> Judging from the link he supplied, he's talking about assemblies generated >> via AssemblyBuilder with the AssemblyBuilderAccess.RunAndCollect flag, which >> can't be saved by ordinary means. >> >> The unmanaged metadata API might be an interesting option, though. Can it >> inspect dynamic assemblies? Depending on what exactly the assembly contains, >> even ordinary Reflection might be enough for the analysis part (don't know >> how well Reflection works for collectible assemblies, though). >> >> Fabian >> >> Gesendet von meinem Windows Phone >> ________________________________ >> Von: Gavin van der Merwe >> Gesendet: 04.07.2012 01:53 >> An: **** >> >> Betreff: Re: [mono-cecil] Serializing CollectibleAssemblies >> >> Hey Fabian >> >> Are you sure about the "in-memory" assumption. I agree with you Cecil does >> not support this at all. It is the primary reason I moved over to the >> unmanaged API. Although Dlux is talking about persisting serialised >> assemblies to disk. >> >> Regards >> >> Gav >> >> On 3 July 2012 10:28, Fabian Schmied wrote: >>> >>> Hi, >>> >>> The Roslyn "C# compiler as a service" project is not part of .NET 4.5, it >>> will probably be released some time after .NET 4.5 (and C# 5). At the >>> moment, it only exists as a technology preview >>> (http://blogs.msdn.com/b/ericlippert/archive/2012/06/05/announcing-microsoft-roslyn-june-2012-ctp.aspx). >>> >>> Since you're talking about non-saveable collectible assemblies generated at >>> runtime, I don't think Cecil will be able to help you at all. Cecil can't >>> analyze dynamic assemblies that only exist in memory, so it can't be used >>> with the "serialization" part. It also can't define dynamic assemblies in >>> memory, so it can't be used for the "deserialization" part either (you'd >>> need to use Reflection.Emit instead). >>> >>> I don't think there is a way to persist a collectible assembly, but maybe >>> you can somehow write the data structures produced by Roslyn to disk before >>> a dynamic assembly is generated. Or can you configure Roslyn to write a >>> non-collectible assembly instead? >>> >>> Best regards, >>> Fabian >>> >>> On Thu, Jun 28, 2012 at 4:26 PM, Dlux wrote: >>>> >>>> I'm referring to the C# compiler services in NET 4.5 that can generate >>>> GC'able assemblies from C# source. >>>> >>>> By serializeable assembly, I mean an assembly that can be saved to disk as >>>> a file. According to an MSDN forums comment, the GC'able assemblies >>>> generated by the NET 4.5 C# compiler cannot be saved out to disk. See >>>> http://social.msdn.microsoft.com/Forums/en-US/dlr/thread/13403a6c-5e73-43d6-9a9a-1a7c2b5626c4 >>>> . I figured you guys would know more about this, thus the question: >>>> Ultimately I want to compile C# code to a discardable assembly, be able to >>>> save that to disk, and be able to load it from disk. I'm not too picky on >>>> the mechanisms - [Serializeable] is pretty old anyway - I just need basic >>>> capability. The only version of NET where you can compile C# to produce a >>>> GC'able assembly is NET 4.5. In all earlier versions, you can produce an >>>> assembly, but it won't GC. Mono won't do it either :-(. So I figure I >>>> can accomplish this by taking together a few techniques: using NET 4.5's >>>> C# compiler to produce a collectible assembly, using Cecil to persist it >>>> to disk in standard format, then using Cecil to interrogate that persisted >>>> assembly and re-create a collectible assembly in memory via >>>> Reflection.Emit. >>>> >>>> In other words, I'm trying to workaround the limitation that a collectible >>>> assembly cannot be loaded by calling Load(filename), and the corollary >>>> that it can't be saved either. >>>> >>>> >> One interesting thing to research is whether it is possible to return a >>>> >> collectible assembly from the AppDomain.AssemblyResolve event. If this >>>> >> is not possible, your code wouldn't be able to statically reference >>>> >> assembly A; everything would need to be triggered >>>> >>>> That's why I'm asking the question! >>>> >>>> David L- >>>> >>>> On Thursday, June 28, 2012 10:02:28 AM UTC-4, Fabian Schmied wrote: >>>>> >>>>> Hi, >>>>> >>>>> First of all, Roslyn is not the same as .NET 4.5, so it's not really >>>>> clear how these assemblies you're talking about are generated. >>>>> Second, when you say "serializeable assembly", what exactly do you mean? >>>>> An assembly that puts the SerializableAttribute on all types within the >>>>> assembly? (This is what Gavin interpreted.) An assembly that you can >>>>> write to disk and read back? (Assemblies can already be stored on disk >>>>> and read back.) >>>>> >>>>> I'm just trying a guess and assume the latter: you have an assembly file >>>>> (DLL file) generated somehow before runtime, and you want to load it, at >>>>> runtime, as a collectible assembly. Is that right? Now, the only way to >>>>> get collectible assemblies into the .NET runtime is to define them using >>>>> Reflection.Emit, so you can't just load them the ordinary way. Instead, >>>>> you'd have to analyze the source assembly's contents and rebuild >>>>> everything in memory using Reflection.Emit. The only part where Cecil can >>>>> help you in this is the analysis part. >>>>> >>>>> Steps: >>>>> - At runtime, somebody needs to use code from assembly A. >>>>> - Use Cecil to read in assembly A. >>>>> - Create a dynamic collectible in-memory assembly with the same full name >>>>> as A. >>>>> - Use Reflection.Emit to redefine everything found within the real >>>>> assembly A in the dynamic assembly. >>>>> >>>>> If this is what you need, this will probably work (although cloning an >>>>> assembly in memory will be a very complex task). However, consider the >>>>> limitations of collectible assemblies listed here: >>>>> http://msdn.microsoft.com/en-us/library/dd554932.aspx. >>>>> >>>>> One interesting thing to research is whether it is possible to return a >>>>> collectible assembly from the AppDomain.AssemblyResolve event. If this is >>>>> not possible, your code wouldn't be able to statically reference assembly >>>>> A; everything would need to be triggered dynamically. >>>>> >>>>> Regards, >>>>> Fabian >>>>> >>>>> On Thu, Jun 28, 2012 at 12:13 AM, Dlux wrote: >>>>>> >>>>>> Good day (or night) fine developers. I am considering using Cecil to >>>>>> create an assembly cloner and loader. This was take assemblies >>>>>> generated by Rosalyn (NET 4.5), clone them to a serializeable assembly >>>>>> that I could then save, and then later reconstruct a CollectibleAssembly >>>>>> from the serialized version. This would be used on file close in an >>>>>> application that uses a great many expressions to convert raw values >>>>>> into unitized values. I'd save the compiled version as a part of the >>>>>> "document", sign it, then on load, if the signature vets, I don't have >>>>>> to recompile them. >>>>>> >>>>>> From looking at Cecil I think I could do this, but I haven't done >>>>>> anything this low-level with assemblies before. Does anyone else have >>>>>> any relevant experience or knowledge on roadblocks or problems I may >>>>>> encounter [attempting to] do this? >>>>>> >>>>>> David L- >>>>>> >>>>>> -- >>>>>> -- >>>>>> mono-cecil >>>>> >>>>> >>>> -- >>>> -- >>>> mono-cecil >>> >>> >>> -- >>> -- >>> mono-cecil >> >> >> -- >> -- >> mono-cecil > > -- > -- > mono-cecil -- -- mono-cecil
