如何使用 Visual Studio 扩展从当前解决方案收集类型

本文关键字:解决方案 类型 何使用 Visual Studio 扩展 | 更新日期: 2023-09-27 18:33:41

我创建了Visual Studio 2012包(使用VS2012 SDK(。此扩展(如果安装在客户端的 IDE 环境中(应具有从开发人员正在处理的当前打开的解决方案中收集所有特定类型的功能。Visual Studio Designer 中嵌入了类似的功能 ASP.NET 用于 MVC 应用程序项目,开发人员在其中实现模型/控制器类,生成项目,然后能够在基架 UI(设计器的下拉列表(中访问此类型。相应的功能在WPF,WinForms Visual Designers等中也可用。

假设我的扩展必须从实现ISerializable接口的当前解决方案中收集所有类型。步骤如下:开发人员创建特定的类,重新生成包含项目/解决方案,然后执行扩展 UI 提供的一些操作,从而涉及执行ISerializable类型收集。

我尝试使用反射实现收集操作:

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

但是上面的代码会导致抛出System.Reflection.ReflectionTypeLoadException异常:

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"}
(...)

如何正确实现从当前生成的解决方案中收集特定类型的操作?

如何使用 Visual Studio 扩展从当前解决方案收集类型

我试图做类似的事情,不幸的是,到目前为止我发现的唯一解决方法是执行以下操作(我觉得这有点混乱,但也许对特定情况进行一些调整可能没问题(

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);
    }
}

这将为您提供所有类型,但您可以过滤掉您想要的任何内容。

引用这篇文章:调用Assembly.GetTypes((时如何防止ReflectionTypeLoadException((

我不确定我是否正确理解了你,但如果我是,这将成功:

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);
}