1

I have some domain classes having a property of type Type (the class).

The user can select any class loaded in his project using a custom TypeBrowserEditor.

The serialization works fine, I serialize as myType.AssemblyQualifiedName

But during the deserialization, Type.GetType(str) returns null since the assembly isn't loaded in the app domain.

I can't do AssemblyLoad(str) because he won't find the file.

I need to have access to the IVSHierarchy and enumerate through the References of the user's project. But i can't find a way to have access to it in my DomainPropertyXmlSerializer. If anyone can point me to the right direction for a service provider or anyway to let me connect to the VS current project it would be great.

Thanks in advance.

Edit : I could worst case scenario only work with String and just cast it in my type editor since i can have access to the IVSHierarchy there but I don't really like that solution.

1 Answers1

0

Ok I managed to do it !

In the DslPackage, make a DocData.cs, and create a part for the MyLanguageDocData class (partial)

then in it :

protected override void OnDocumentLoading(EventArgs e)
    {
        mRes = new ResolveEventHandler(CustomAssemblyResolverDocData);
        availableTypes = new Dictionary<string, Type>();
        availableAssemblies = new Dictionary<string, Assembly>();
        PreloadAssemblies();
        if (availableAssemblies.Count == 0)
            throw new Exception("Problem");

        base.OnDocumentLoading(e);
        AppDomain.CurrentDomain.TypeResolve += mRes;
        AppDomain.CurrentDomain.AssemblyResolve += mRes;
    }

The exception happens when the designer is opened before the solution is loaded (happens when you closed visual studio while editing your design). Throwing an exception here will prevent the load from happening silently.

In the PreloadAssemblies :

IVsHierarchy hier = VsHelper.ToHierarchy(dteProject);
DynamicTypeService typeService = (DynamicTypeService)this.GetService(typeof(DynamicTypeService));
ITypeDiscoveryService discovery = typeService.GetTypeDiscoveryService(hier);

try
{

    foreach (Type type in discovery.GetTypes(typeof(object), true))
    {
        if (!availableTypes.ContainsKey(type.FullName))
        {
            availableTypes.Add(type.FullName, type);
        }
        if (!availableAssemblies.ContainsKey(type.Assembly.GetName().Name))
        {
            availableAssemblies.Add(type.Assembly.GetName().FullName, type.Assembly);
        }
    }
}
catch (Exception e)
{

}

And in the resolver just check if the assembly name is in the dictionary. otherwise return null.

override the DocumentClosed as well to remove the Assembly resolver :)