http://blogs.clariusconsulting.net/kzu

Daniel Cazzulino's Blog

Go Back to
kzu′s Latest post

How to get a System.Type from an EnvDTE.CodeTypeRef or EnvDTE.CodeClass

I have already hinted at this in a previous post, but this time it's a bit different. Sometimes it's useful to switch to a full System.Type when you're doing code-generation or general CodeModel navigation within VS in an addin or VSSDK package.

The trick is to retrieve the ITypeResolutionService from the DynamicType associated with the current project:

private ITypeResolutionService GetResolutionService()
{
    DynamicTypeService typeService = GetService<DynamicTypeService>();
    Debug.Assert(typeService != null, "No dynamic type service registered.");

    IVsSolution sln = GetService<IVsSolution>();
    IVsHierarchy hier;
    sln.GetProjectOfUniqueName(CurrentProject.Project.UniqueName, out hier);

    Debug.Assert(hier != null, "No active hierarchy is selected.");

    return typeService.GetTypeResolutionService(hier);
}

[GetService<T> is just a shorthand to an IServiceProvider.GetService call. The service provider should be the one associated with the current project]

With the resolver at hand, you can simply do:

CodeTypeRef type = // some type you gotType t = resolver.GetType(type.AsFullName, true);

or

CodeClass cc = // some class you gotType t = resolver.GetType(cc.FullName, true);

 

One caveat:  this is very reliable if the type you're loading is external (i.e. it's CodeClass.InfoLocation == vsCMInfoLocation.vsCMInfoLocationExternal) but for classes on the current project, you'll get a type that contains the code from the last successful compilation. Alternatively, you can force a compilation before going this route, although I'd advise against it: it's not a very good user experience IMO.

Comments

6 Comments

  1. HI
    This was quite useful. I have a related question. Is it possible to find the “Reference” from which this CodeTypeRef object is added ? (One way is to use the Type.Assembly property.)

    thanks
    -Pramod

  2. Hi!
    Awesome article, but I have some problems while trying to use the code.
    I can’t find where Microsoft.VisualStudio.Shell.Design.dll is, needed to use DynamicTypeService class. I’ve searched via Google with no results.

    Any suggestion, please?
    Thanks a lot!

  3. I’m trying to get DynamicTypeService in a T4 template; when I ask for it, I get an error stating that DynamicTypeService is not marked as serializable.
    Is there any other way to get to the ITypeResolutionService for a project at desing time?

    IServiceProvider serviceProvider = (IServiceProvider)this.Host;
    DynamicTypeService typeService = (DynamicTypeService)serviceProvider.GetService(typeof(DynamicTypeService));

  4. Alas, this method doesn’t work if types are defined in referenced classes.