I use the IVsObjectList2.GetCategoryField2
method to retrieve different information of a type.
Now I wonder how I can retrieve C# specific information like abstract
or internal
modifier of a type?
The Object Browser can displays this informations.
Update 1:
I have made another attempt to get this information. Via the DynamicTypeService
and the IVsHierarchy
(of the project) I can get the TypeResolutionService
. This can then return the Type
I'm are looking for, and form the Type I get the infomrations (internal, abstract, etc.)
Unfortunately, this only works with .NET Framework projects. .NET Core projects don't work. The assumption is that .NET core projects cause problems when resolving, because the VS add-in (or Visual Studio SDK) run under .NET Framework.
var dte = Package.GetGlobalService(typeof(DTE)) as DTE2;
var serviceProvider = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte);
IVsSimpleObjectList2 objectList;
....
objectList.CountSourceItems(index, out var vsHierarchy, out var itemid, out var pcItems);
DynamicTypeService dynamicTypeService = (DynamicTypeService)serviceProvider.GetService(typeof(DynamicTypeService));
var typeResolutionService = dynamicTypeService.GetTypeResolutionService(hier);
var type = typeResolutionService.GetType("ObjectBuilder.ObjectBrowserTestTypes.AbstractTestClass");
More Infos here: Visual Studio Extension get all classes and interfaces metadata
I'm still looking for a solution. Does anyone have another idea?
At the end, I decided not to retrieve the information about the types via the Object-Browser or IVsObjectManager2
. The reason is that I didn't get all the information I needed.
For types in the currently loaded visual studio projects I'm using the ElementClass
or CodeClass
class.
var service = Package.GetGlobalService(typeof(DTE)) as DTE2;
Project project = service?.Solution?.Projects.Item(0);
CodeType codeType = project.CodeModel.CodeTypeFromFullName("Full name of Type");
if (codeType.Kind == vsCMElement.vsCMElementClass && codeType is CodeClass2 codeClass)
{
// get all the information form the code class
var typeDescription = new TypeDescription();
typeDescription.FullName = codeClass.FullName;
typeDescription.ContainsGenericParameters = codeClass.IsGeneric;
typeDescription.IsAbstract = codeClass.IsAbstract;
}
For types that are in a referenced assembly I'm using Mono.Cecil. The advantage of Mono.Cecil is, that it works with .NET Framework DLLs and .NET Core DLLs. The path of the referenced assembly can be gotten via the VS-SDK.
var vsProject = project.Object as VSLangProj.VSProject;
var assemblyPath = vsProject.References.Item(0).Path;
ModuleDefinition module = Mono.Cecil.ModuleDefinition.ReadModule(assemblyPath);
foreach (TypeDefinition type in module.Types)
{
var isAbstract = type.IsAbstract;
}