views:

157

answers:

1

I'm working on a visual studio 2008 add-in that will generate data-access code by looking at the method signature combined with a set of options the user enters in a dialog.

For analyzing the method signature I use the ITypeResolutionService of visual studio to lookup a type that either exists in the current project, in the referenced projects or in the referenced assemblies.

For this I created the following functionality:

private ITypeResolutionService _typeResolutionService;
private ITypeDiscoveryService _typeDiscoveryService;

/// <summary>
/// Initializes a new instance of the TypeResolver class.
/// </summary>
public TypeResolver(VisualStudioServiceProvider serviceProvider, Project project)
{
    IVsSolution solution = serviceProvider.GetService<IVsSolution>();
    DynamicTypeService typeResolver = serviceProvider.GetService<DynamicTypeService>();

    IVsHierarchy hierarchy = null;
    solution.GetProjectOfUniqueName(project.UniqueName, out hierarchy);

    _typeResolutionService = typeResolver.GetTypeResolutionService(hierarchy);
    _typeDiscoveryService = typeResolver.GetTypeDiscoveryService(hierarchy);
}

/// <summary>
/// Resolves a type in the current solution
/// </summary>
/// <param name="name">Name of the type to resolve</param>
/// <returns>Returns the resolved type; otherwise null</returns>
public Type Resolve(string name)
{
    return _typeResolutionService.GetType(name, true);
}

It does resolve non-generic types, but sadly doesn't work on generic types. Does anybody have an idea on how to get the above snippet working for generic types too?

+2  A: 

The type of a generic type is the type of its type parameter at runtime. At design time, a generic type has no type, because the parameterized type has not been specified. It's probably not working because no class instance exists at the time GetType is called.

This is the same reasoning that prevents generic types from being used as arguments. You cannot specify a generic type without specifying the actual type of the T.

Robert Harvey
That's correct, however I'm specifying the following type to be resolved:"System.Collections.ObjectModel.Collection<Client>" This doesn't resolve correctly. Applying the logic you just described I also tried the following:"System.Collections.ObjectModel.Collection`1[[MyNamespace.Client]]" This however doesn't work either.
W.Meints
If I understand the GetType method correctly, it doesn't accept a running instance as a parameter, but rather the name of a type. I don't see how that will translate to a running instance. The GetType method is most likely reflecting over the class definition to obtain its type information.
Robert Harvey
I discovered that when I first call Resolve("MyNamespace.Client") and resolve System.Collections.ObjectModel.Collection`1[[MyNamespace.Client]] after that it works and I get the correct type.Looks like the assembly for the generic argument isn't loaded.
W.Meints
Thanks Robert, In the end I tried the alternative naming scheme and fixed the problem of the assembly not being loaded and the type can now be found.
W.Meints
I know this was 6 months ago, but trying this may work:System.Collections.ObjectModel.Collection`1[[MyNamespace.Client, AssemblyWhereClientObjectIsDefined]]Where 'AssemblyWhereClientObjectIsDefined' is the name of the assembly where your Client object is defined.
Doug