views:

109

answers:

2

Dear ladies and sirs.

Observe the following piece of Silverlight code:

foreach (AssemblyPart ap in Deployment.Current.Parts)
{
  var sri = Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative));
  var assembly = new AssemblyPart().Load(sri.Stream);
  // Do something with the assembly.
}

It iterates over all the assemblies available to the application and does something on them. The problem with this code is that even if that something is just reading the assembly manifest, the code loads the complete assemblies into the process space.

Is it possible to optimize it somehow?

I have similar .NET code, which uses PostSharp.Core library to just read the assembly manifests, without loading the complete assemblies (Mono.Cecil does the job as well).

Thanks in advance to all the good Samaritans out there.

A: 

As you can do in any .NET code:

foreach (AssemblyPart ap in Deployment.Current.Parts)
{
    byte[] buffer = new byte[1024];
    List<byte> assemblyBytes = new List<byte>();

    using (var sri = Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative)).Stream)
    {
        int read = -1;
        do
        {
            read = sri.Read(buffer, 0, buffer.Length);
            if (read != -1)
            {
                Array.Resize(ref buffer, read);
                assemblyBytes.AddRange(buffer);
            }
        }
        while (read != -1);
    }

    var assembly = Assembly.ReflectionOnlyLoad(assemblyBytes.ToArray());
    // Do something with the assembly.     
}

Edited to add

The trick here is to replace the reference to mscorlib [2.0.5.0] with the mscorlib [2.0.0.0] to achieve what you need.

However, it'd be better if you create a separated assembly in order to do this, because replacing the reference might screw up other parts of your code.

Paulo Santos
Only there is a small problem - Silverlight platform does not have the Assembly.ReflectionOnlyLoad method.
mark
True, it's in the `System.Reflection` Namespace. And Silverlight is built over the .NET platform.
Paulo Santos
@Paulo, Have you tried to compile your code in a Silverlight class library? Please, try if you did not and then change your reply accordingly.
mark
@mark, yes it compiles... with a wee bit of incentive.. :-P
Paulo Santos
I do not see how can I utilize this hack, because my code truly runs in a browser and so it cannot load non silverlight assemblies, can it?
mark
There's only one way to find out...
Paulo Santos
A: 

There is no built in way to do this in the silverlight framework. You could try looking at something like Cecil or Microsoft's Common Compiler Infrastructure - Metadata projects to try to run these in SL. Doing so would certainly require recompiling either and I'm unsure of any dependencies. Short of that, you'd be left with implementing your own code that would parse the assembly bytes. Doing this is not for the faint of heart, and would require significant duplication of source with the 2 projects I mention.

Peter Oehlert