序列化类型的域类型

时间:2012-07-18 17:18:10

标签: c# visual-studio-2010 dsl envdte

我有一些域类具有Type(类)的属性。

用户可以使用自定义TypeBrowserEditor选择在他的项目中加载的任何类。

序列化工作正常,我序列化为myType.AssemblyQualifiedName

但是在反序列化期间,Type.GetType(str)返回null,因为程序集未在应用程序域中加载。

我无法执行AssemblyLoad(str),因为他找不到该文件。

我需要访问IVSHierarchy并通过用户项目的References进行枚举。但我找不到在DomainPropertyXmlSerializer中访问它的方法。如果有人能指出我为服务提供商提供正确的方向,或者无论如何让我连接到VS当前的项目,那就太棒了。

提前致谢。

编辑:我可能最糟糕的情况只能使用String并将其投射到我的类型编辑器中,因为我可以访问那里的IVSHierarchy但我真的不喜欢这个解决方案。

1 个答案:

答案 0 :(得分:0)

好的,我设法做到了!

在DslPackage中,创建一个DocData.cs,并为MyLanguageDocData类创建一个部分(部分)

然后在其中:

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

在加载解决方案之前打开设计器时会发生异常(当您在编辑设计时关闭visual studio时)。 在这里抛出异常将防止负载无声地发生。

在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)
{

}

在解析器中只检查程序集名称是否在字典中。否则返回null。

也会覆盖DocumentClosed以删除Assembly解析器:)