问题
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 ISerializable
types 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?
回答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()
回答2:
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);
}
来源:https://stackoverflow.com/questions/19142579/how-to-collect-types-from-current-solution-using-visual-studio-extension