6

I have created Visual Studio 2012 Package (using VS2012 SDK). This Extension (if installed on the client's IDE environment) should has, among other things, a functionality of collecting all specific types from currently opened solution which developer is working on. A similar feature is embedded in Visual Studio Designer for ASP.NET MVC Application Project, where developer implements a Model/Controller class, build a project, and then is able to access this type in Scaffolding UI (Designer's dropdown list). The corresponding features are also available in WPF, WinForms Visual Designers, etc.

Let's say that my extension has to collect all types from current solution, which implement ISerializable interface. The steps are following: Developer creates specific class, rebuild containing project/solution, then do some action provided by extension UI, thus involves performing ISerializabletypes collecting.

I have tried to implement collecting operation using reflection:

List<Type> types = AppDomain.CurrentDomain.GetAssemblies().ToList()
                  .SelectMany(s => s.GetTypes())
                  .Where(p => typeof(ISerializable).IsAssignableFrom(p) && !p.IsAbstract).ToList();

But above code causes System.Reflection.ReflectionTypeLoadException exception to be thrown:

System.Reflection.ReflectionTypeLoadException was unhandled by user code
  HResult=-2146232830
  Message=Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
  Source=mscorlib
  StackTrace:
       at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
       at System.Reflection.RuntimeModule.GetTypes()
       at System.Reflection.Assembly.GetTypes()
(...)  
LoaderException: [System.Exception{System.TypeLoadException}]
{"Could not find Windows Runtime type   'Windows.System.ProcessorArchitecture'.":"Windows.System.ProcessorArchitecture"}
(...)

How can I properly implement operation of collecting specific types from currently built solution?

sgnsajgon
  • 664
  • 2
  • 13
  • 56
  • Related topic: [HowTo get all interfaces types from visual studio solution?](http://stackoverflow.com/questions/13051397/howto-get-all-interfaces-types-from-visual-studio-solution) – sgnsajgon Oct 02 '13 at 18:24
  • I found some sample code in related topic [Finding a ProjectItem by type name via DTE](http://stackoverflow.com/questions/2549186/finding-a-projectitem-by-type-name-via-dte) But this iterative approach is very, very slow. In my VS solution with about 60 project this code is executed a dozen or so seconds, therefore it is not absolutely acceptable solution. I guess it's time consuming operation, but I believe there is a faster way to reach a goal. Resharper and it's types collecting module does this job faster during initialization. – sgnsajgon Oct 03 '13 at 14:22
  • 1
    Any joy with your search for a solution? – JDandChips Jul 16 '14 at 14:32

2 Answers2

1

I was trying to do a similar thing and unfortunately the only way around this I've found so far is by doing the following (which I feel is a bit messy, but maybe with some tweaking for a specific situation might be ok)

var assemblies = AppDomain.CurrentDomain.GetAssemblies();
IEnumerable<Type> types = assemblies.SelectMany(x => GetLoadableTypes(x));

...

public static IEnumerable<Type> GetLoadableTypes(Assembly assembly)
{
    try
    {
        return assembly.GetTypes();
    }
    catch (ReflectionTypeLoadException e)
    {
        return e.Types.Where(t => t != null);
    }
}

This would give you all types, but you can filter out whatever you wish.

Referenced this post: How to prevent ReflectionTypeLoadException when calling Assembly.GetTypes()

Community
  • 1
  • 1
JDandChips
  • 9,780
  • 3
  • 30
  • 46
  • 1
    I used [CodeDOM](http://msdn.microsoft.com/en-us/library/y2k85ax6%28v=vs.110%29.aspx) module to traverse solution elements inside VS plugin, the same that is used by T4. [The Roslyn](http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx) will be great solution, but currently it's in beta stage. I realize that it's impossible to gather types info from VS plugin using standard reflection mechanism, because that solution types are not loaded into plugin CLR AppDomain. I know that Jetbrain's Resharper uses it's own parsing and traversing module, maybe accessible with the aid of R# developers API. – sgnsajgon Jul 17 '14 at 08:18
0

I'm not sure if I understand you correctly, but if I am this will make it:

var assembly = Assembly.GetExecutingAssembly();
IEnumerable<Type> types = 
      assembly.DefinedTypes.Where(t => IsImplementingIDisposable(t))
                           .Select(t => t.UnderlyingSystemType);

........

private static bool IsImplementingIDisposable(TypeInfo t)
{
     return typeof(IDisposable).IsAssignableFrom(t.UnderlyingSystemType);
}
NValchev
  • 2,855
  • 2
  • 15
  • 17
  • This code snippet collects only `IDisposable` types which are implemented in the same assembly/project as it is placed in, in the assembly that is part of the Package. But I need to collect types that are implemented in any other solution of any developer who has installed and use my Package. Types, that not necessarily exists in my Package source code and assemblies. – sgnsajgon Oct 02 '13 at 18:22