进一步分析BAML解析器。
因为还需要维护公司的CRM2011系统,两天没有进行这方面工作。
面对着巨量的数据,解开BAML这把锁对我目前的工作,至关重要。没有什么别的选择。
虽然前面用ILSpy,已进行了许多工作,但实际上,解析出来的XAML仍然要进行大量的手工更改,既然做了这件事,就还是做出一个完善的。
手工改一个XAML就需要一上午至少,所以,完全不如改进解析器来得上算,而且,改好后,所有的BAML都可以不用手工改就OK。
总之,还要回头再来。
通过前面的分析,我已经从所面对的二进制码中,找到我所关注的。
我们不是要抄袭,而是只需关注其中有用的那一点,当然,冰山的一角,对我们来说,也是巨大的宝库。
(目前我最关注的,就是界面视图的动态切换过程。
事实上,我已部分分析出,切换的过程,老外的确有他们的心得。是用绑定和convertor来实现。很新奇,但也合理。以后有时间,我再讲这一块。)
因为,人家是一个团队的实现,而我们中国,哪有几个能干活的团队。要想又能用,又有框架,在框架这个阶段,学习国外成熟的工业产品的框架,是十分必要的。
说来说去,是体制的问题,体制的问题,本反是人性的问题。
一个没有信仰的民族,结局只能是只有小聪明,没有大智慧。
但是,人要极积向上。我还得活着,不是么。
一个人,改变不了别人的时候,要么改变自己,要么,就要一个人顶十个,甚至顶100个。总之,一个真正的男人,要不断地想办法。
我的办法,就是在最底层,开发出工具,放这些工具,能成为我的帮手。程序员嘛,就那么点事,人帮不了你的时候,就得求助于计算机。
==================
从两个方向,在分析。
一方面,看了Reflector 的baml viewer 插件,它在一些方面,反倒是比ILSPY好得多。
特别是在数据绑定的部分。
但Ilspy也有特另之处,比如,能找到根节点的真实类名,
比如一个wpf页面,基于础Grid,baml viewer就不行。
所以,分别分析了两方面的代码。
对于找基类名称这个过程,ILSpy,是做得相当牛的,这一个小功能,事实上,是一个大动作
void ReadElementStart()
{
LayerPush();
short identifier = reader.ReadInt16();
sbyte flags = reader.ReadSByte();
if (flags < 0 || flags > 3)
throw new NotImplementedException();
Debug.Print("ElementFlags: " + flags);
TypeDeclaration declaration = GetTypeDeclaration(identifier);
XmlBamlElement element;
XmlBamlElement parentElement = null;
if (elements.Count > 0)
{
parentElement = elements.Peek();
element = new XmlBamlElement(parentElement);
element.Position = this.reader.BaseStream.Position;
// Porto l'inizio del padre all'inizio del primo figlio
if (parentElement.Position == 0 && complexPropertyOpened == 0)
parentElement.Position = element.Position;
}
else
element = new XmlBamlElement();
// the type is defined in the local assembly, i.e., the main assembly
// and this is the root element
TypeDeclaration oldDeclaration = null;
if (_resolver.IsLocalAssembly(declaration.Assembly) && parentElement == null) {
oldDeclaration = declaration;
declaration = GetKnownTypeDeclarationByName(declaration.Type.BaseType.AssemblyQualifiedName);
}
//这里的意思,还是很明确的,ILspy体系里,自带了一个真正的二进制码引挚,所以,可以遍历当前类的所有的基类,直到找到一个类,符合根节点策略。
还是很佩服这些人,真是敬业。
TypeDeclaration GetKnownTypeDeclarationByName(string assemblyQualifiedName)
{
foreach (var type in KnownInfo.KnownTypeTable) {
if (assemblyQualifiedName == type.AssemblyQualifiedName)
return type;
}
return new ResolverTypeDeclaration(_resolver, assemblyQualifiedName);
}
当然,也不是说baml viewer就一无是处。它的实现简洁明了。
比如,一个好处是方便操作文本格式。
下班了,回家做饭了。以后再补充,比如如何把baml viewer 挂到ilspy中。以加快调试进行,因为使用reflector调试,很慢,也不清楚原因。