Answered How do I enumerate Symbols in an Assembly?

  • Saturday, November 19, 2011 2:15 AM
     
     

    How can I enumerate the Symbols in an Assembly? I'd like to use Roslyn as a substitute for Reflection. In this scenario I have no source code that I'm compiling. I just want to reflect over a set of already compiled assemblies using Roslyn instead of Reflection. I want to do this because Roslyn doesn't actually load the assemblies like Reflection does.

    And a related question, what happens if I start reflection over an assembly created by the VB compiler using the C# Symbol class hierarchy? What happens when I run across a language construct that that VB supports but C# does not support? Did you guys come up with a good solution to that problem? 

    Thanks,
    Chris 


    • Edited by kingces95 Saturday, November 19, 2011 2:15 AM
    •  

All Replies

  • Saturday, November 19, 2011 10:40 AM
     
     

    As far as I know, Roslyn isn't meant to be a substitute for Reflection and can't be used that way. What you want to do sound like a job for Reflection. If you really need to unload the assemblies after use, you could load them into another AppDomain and then uload that.

    And assemblies don't contain C# or VB language constructs, they contain CIL code. You can try to guess what C#/VB code could produce this CIL, which is exactly what tools like Reflector or dotPeek do. But it's only that – a guess, and it can't work perfectly, because there are some CIL constructs that can't be expressed in those languages.

    • Proposed As Answer by svick Saturday, November 19, 2011 10:41 AM
    • Unproposed As Answer by kingces95 Sunday, November 20, 2011 9:29 AM
    •  
  • Saturday, November 19, 2011 9:01 PM
     
     Answered Has Code

    Its true there are things that Reflection can do that Roslyn cannot (e.g. late bound operations like Invoke) but it is also true the Roslyn can do that Reflection cannot (e.g. load assemblies into the same AppDomain without affecting the binding context of the current AppDomain). Minus that there is vast overlap.

    For example, Roslyn is intended to be the back end for the VS object browser. To build an object browser the first step would be to load and reflect over the types in an Assembly. And, as it turns out, there is a way to create a "loader context" in Roslyn and start reflecting over an assemblies:

        var reference = MetadataReference.Crate("c:\foo.dll");
        var references = new[] { reference };
        var compilation = Compilation.Create("LoaderContext", references: references);
        var assembly = compilation.GetReferencedAssemblySymbol(reference);
        var globalNs = assembly.GlobalNamespace;
        var types = gloablNs.GetTypeMembers();

    It's just not quite as familiar as Reflections assembly.GetTypes() but it works! Well almost, compilation.GetTypeByMetadataName doesn't seem to work if you pass an AQN but that looks like a bug.

    Thanks,
    Chris 


    • Proposed As Answer by svick Saturday, November 19, 2011 9:31 PM
    • Unproposed As Answer by svick Saturday, November 19, 2011 9:31 PM
    • Edited by kingces95 Sunday, November 20, 2011 9:30 AM
    • Marked As Answer by kingces95 Sunday, November 20, 2011 9:30 AM
    •  
  • Saturday, November 19, 2011 9:13 PM
     
     

    SVick, don't you think its funny that there is a CSharp.Symbol and a VisualBasic.Symbol given, as you say, assemblies contain IL and not language constructs? If that's the case why associate a Symbol abstraction, which can be retrieved out of any assembly, with a language that it may or may not have been created with? What do you think?

    Thanks,
    Chris 

  • Sunday, November 20, 2011 5:58 AM
     
     

    I kind of need to enumerate symbols too.

    Would a SymbolVisitor make sense ?

  • Wednesday, November 23, 2011 1:39 AM
    Owner