// Return the Type ID for the passed typeFullName by creating a new record and adding // it to the type info hashtable. A BamlTypeInfoRecord is created if there is no serializer // for this type, and a BamlTypeInfoWithSerializerRecord is created if there is a serializer. internal short AddTypeInfoMap(BinaryWriter binaryWriter, string assemblyFullName, string typeFullName, Type elementType, string serializerAssemblyFullName, string serializerTypeFullName) { TypeInfoKey key = GetTypeInfoKey(assemblyFullName, typeFullName); BamlTypeInfoRecord bamlTypeInfoRecord; // Create either a normal TypeInfo record, or a TypeInfoWithSerializer record, depending // on whether or not there is a serializer for this type. if (serializerTypeFullName == string.Empty) { bamlTypeInfoRecord = new BamlTypeInfoRecord(); } else { bamlTypeInfoRecord = new BamlTypeInfoWithSerializerRecord(); short serializerTypeId; // If we do not already have a type record for the serializer associated with // this type, then recurse and write out the serializer assembly and type first. if (!GetTypeInfoId(binaryWriter, serializerAssemblyFullName, serializerTypeFullName, out serializerTypeId)) { serializerTypeId = AddTypeInfoMap(binaryWriter, serializerAssemblyFullName, serializerTypeFullName, null, string.Empty, string.Empty); } ((BamlTypeInfoWithSerializerRecord)bamlTypeInfoRecord).SerializerTypeId = serializerTypeId; } bamlTypeInfoRecord.TypeFullName = typeFullName; // get id for assembly BamlAssemblyInfoRecord bamlAssemblyInfoRecord = AddAssemblyMap(binaryWriter, assemblyFullName); bamlTypeInfoRecord.AssemblyId = bamlAssemblyInfoRecord.AssemblyId; bamlTypeInfoRecord.IsInternalType = (elementType != null && ReflectionHelper.IsInternalType(elementType)); // review, could be a race condition here. bamlTypeInfoRecord.TypeId = (short) TypeIdMap.Add(bamlTypeInfoRecord); // add to the hash ObjectHashTable.Add(key,bamlTypeInfoRecord); // Write to BAML bamlTypeInfoRecord.Write(binaryWriter); return bamlTypeInfoRecord.TypeId; }
// Return a type info record for a type identified by the passed ID. If the // ID is negative, then this is a known type, so manufacture a BamlTypeInfoRecord // for it. internal BamlTypeInfoRecord GetTypeInfoFromId(short id) { // If the id is less than 0, it is a known type that lives in the // known assembly, so manufacture a type info record for it. if (id < 0) { // For some types, we create a TypeInfo record with serializer information. For // all other types, we create a regular TypeInfo record. // NOTE: When serializers are publically extensible, then this should be // reflected for as part of the KnownElementsInitializer. BamlTypeInfoRecord info; if (-id == (short)KnownElements.Style) { info = new BamlTypeInfoWithSerializerRecord(); ((BamlTypeInfoWithSerializerRecord)info).SerializerTypeId = -(int) KnownElements.XamlStyleSerializer; ((BamlTypeInfoWithSerializerRecord)info).SerializerType = KnownTypes.Types[(int)KnownElements.XamlStyleSerializer]; info.AssemblyId = -1; } else if (-id == (short)KnownElements.ControlTemplate || -id == (short)KnownElements.DataTemplate || -id == (short)KnownElements.HierarchicalDataTemplate || -id == (short)KnownElements.ItemsPanelTemplate) { info = new BamlTypeInfoWithSerializerRecord(); ((BamlTypeInfoWithSerializerRecord)info).SerializerTypeId = -(int) KnownElements.XamlTemplateSerializer; ((BamlTypeInfoWithSerializerRecord)info).SerializerType = KnownTypes.Types[(int)KnownElements.XamlTemplateSerializer]; info.AssemblyId = -1; } else { // Search the Assembly table to see if this type has a match. If not, then // we know that it is a known assembly for an Avalon known type. We have to do // this since some of the known types are not avalon types, such as Bool, Object, // Double, and others... info = new BamlTypeInfoRecord(); info.AssemblyId = GetAssemblyIdForType(KnownTypes.Types[-id]); } info.TypeId = id; info.Type = KnownTypes.Types[-id]; info.TypeFullName = info.Type.FullName; return info; } else { return (BamlTypeInfoRecord) TypeIdMap[id]; } }
// Create a serializer, given a type info record with serializer information. private XamlSerializer CreateSerializer( BamlTypeInfoWithSerializerRecord typeWithSerializerInfo) { // ID less than 0 means a known serializer in PresentationFramework. // if (typeWithSerializerInfo.SerializerTypeId < 0) { return (XamlSerializer)MapTable.CreateKnownTypeFromId( typeWithSerializerInfo.SerializerTypeId); } else { // If the serializer type hasn't been determined yet, do it now. if (typeWithSerializerInfo.SerializerType == null) { typeWithSerializerInfo.SerializerType = MapTable.GetTypeFromId( typeWithSerializerInfo.SerializerTypeId); } return (XamlSerializer)CreateInstanceFromType( typeWithSerializerInfo.SerializerType, typeWithSerializerInfo.SerializerTypeId, false); } }