internal IEnumerable <ITypeModelDifference> FindDifferences(TypeDescription otherType) { if (SerializationType != otherType.SerializationType) { return new[] { new SerializationTypeChanged(otherType.AssemblyQualifiedName, SerializationType, otherType.SerializationType) } } ; switch (SerializationType) { case SerializationType.ByReference: return(FindByReferenceDifferences(otherType)); case SerializationType.ByValue: return(FindByValueDifferences(otherType)); case SerializationType.Singleton: return(FindSingletonDifferences(otherType)); default: throw new NotImplementedException(); } }
private IEnumerable <ITypeModelDifference> FindSingletonDifferences(TypeDescription otherType) { throw new NotImplementedException(); }
/// <summary> /// Creates a new description for the given type. /// </summary> /// <param name="type"></param> /// <param name="typesByAssemblyQualifiedName"></param> /// <param name="assumeByReference"></param> /// <returns></returns> public static TypeDescription Create(Type type, IDictionary <string, TypeDescription> typesByAssemblyQualifiedName, bool assumeByReference = false) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var assemblyQualifiedName = type.AssemblyQualifiedName; if (assemblyQualifiedName == null) { throw new ArgumentException("Type.AssemblyQualifiedName should not be null"); } bool builtIn, isEnumerable; MethodInfo singletonAccessor; Type byReferenceInterface; var serializerType = GetSerializationType(type, assumeByReference, out builtIn, out isEnumerable, out singletonAccessor, out byReferenceInterface); var description = new TypeDescription(type, byReferenceInterface) { AssemblyQualifiedName = assemblyQualifiedName, SerializationType = serializerType }; typesByAssemblyQualifiedName.Add(assemblyQualifiedName, description); var serializationCallbacks = GetSerializationCallbacks(type, typesByAssemblyQualifiedName); switch (description.SerializationType) { case SerializationType.ByValue: description.Fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly) .Where(x => x.GetCustomAttribute <DataMemberAttribute>() != null) .Select(x => FieldDescription.Create(x, typesByAssemblyQualifiedName)).ToArray(); description.Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(x => x.GetCustomAttribute <DataMemberAttribute>() != null) .Select(x => PropertyDescription.Create(description, x, typesByAssemblyQualifiedName)).ToArray(); description.Methods = serializationCallbacks; break; case SerializationType.ByReference: if (serializationCallbacks.Any()) { throw new ArgumentException( string.Format( "The type '{0}.{1}' is marked with the [ByReference] attribute and thus may not contain serialization callback methods", type.Namespace, type.Name)); } description.Fields = new FieldDescription[0]; description.Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(x => PropertyDescription.Create(description, x, typesByAssemblyQualifiedName)).ToArray(); description.Methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => !x.IsSpecialName) .Select(x => MethodDescription.Create(x, typesByAssemblyQualifiedName)).ToArray(); break; case SerializationType.Singleton: if (serializationCallbacks.Any()) { throw new ArgumentException( string.Format( "The type '{0}.{1}' is a singleton and thus may not contain any serialization callbacks", type.Namespace, type.Name)); } description.Fields = new FieldDescription[0]; description.Properties = new PropertyDescription[0]; description.Methods = new[] { MethodDescription.Create(singletonAccessor, typesByAssemblyQualifiedName) }; break; case SerializationType.Unknown: description.Fields = new FieldDescription[0]; description.Properties = new PropertyDescription[0]; description.Methods = new MethodDescription[0]; break; case SerializationType.NotSerializable: // TODO: Throw proper exception with proper error message throw new NotImplementedException(); default: throw new NotImplementedException(); } if (IsInterestingBaseType(type.BaseType)) { description.BaseType = GetOrCreate(type.BaseType, typesByAssemblyQualifiedName); } description.IsBuiltIn = builtIn; description.IsValueType = type.IsValueType; description.IsClass = type.IsClass; description.IsInterface = type.IsInterface; description.IsEnum = type.IsEnum; description.IsEnumerable = isEnumerable; description.IsSealed = type.IsSealed; description.IsGenericType = type.IsGenericType; if (type.IsGenericType) { var genericArguments = type.GetGenericArguments(); var types = new TypeDescription[genericArguments.Length]; for (int i = 0; i < genericArguments.Length; ++i) { types[i] = GetOrCreate(genericArguments[i], typesByAssemblyQualifiedName); } description.GenericArguments = types; } else if (type.IsArray) { description.GenericArguments = new[] { GetOrCreate(type.GetElementType(), typesByAssemblyQualifiedName) }; } else { description.GenericArguments = new TypeDescription[0]; } if (type.IsEnum) { var storageType = Enum.GetUnderlyingType(type); description.StorageType = GetOrCreate(storageType, typesByAssemblyQualifiedName); var values = Enum.GetValues(type).OfType <object>().ToArray(); var names = Enum.GetNames(type); var descriptions = new EnumValueDescription[values.Length]; for (int i = 0; i < names.Length; ++i) { descriptions[i] = EnumValueDescription.Create(storageType, values[i], names[i]); } description.EnumValues = descriptions; } return(description); }