public override Type Visit(Type type) { if (type.TryGetCarriedType(out var carriedType)) { if (!_parent.Entities.ContainsKey(type)) { if (DataTypeHelpers.IsStructuralEntityDataTypeCached(carriedType)) { var structuralType = (StructuralDataType)DataTypeHelpers.FromTypeCached(carriedType, allowCycles: true); _parent.Entities[type] = structuralType; } else { // // Non-generic record types or anonymous types (created by RuntimeCompiler) may contain entities, // so we have to grab those as well. // if (!carriedType.IsGenericType && DataTypeHelpers.TryFromTypeCached(carriedType, allowCycles: true, out var result) && result.Kind == DataTypeKinds.Structural) { var structuralType = (StructuralDataType)result; var runtimeCompilerTypes = StructuralDataTypeKinds.Anonymous | StructuralDataTypeKinds.Record; if ((runtimeCompilerTypes & structuralType.StructuralKind) != 0) { _parent.Entities[type] = structuralType; } } } } if (!_parent.Enumerations.ContainsKey(type)) { if (DataTypeHelpers.IsEntityEnumDataTypeCached(carriedType)) { var primitiveType = (PrimitiveDataType)DataTypeHelpers.FromTypeCached(carriedType, allowCycles: true); Debug.Assert(primitiveType.PrimitiveKind == PrimitiveDataTypeKinds.EntityEnum); _parent.Enumerations[type] = primitiveType; } } } return(base.Visit(type)); }
/// <summary> /// Creates a slim representation of a type constructor. /// </summary> /// <param name="originalConstructor">The original constructor.</param> /// <param name="declaringTypeSlim">The slim representation of the declaring type.</param> /// <param name="parameterTypeSlims">The slim representations of the constructor parameter types.</param> /// <returns>The slim representation of the constructor.</returns> protected override ConstructorInfoSlim GetConstructorCore(ConstructorInfo originalConstructor, TypeSlim declaringTypeSlim, ReadOnlyCollection <TypeSlim> parameterTypeSlims) { var slimConstructor = base.GetConstructorCore(originalConstructor, declaringTypeSlim, parameterTypeSlims); var parameters = originalConstructor.GetParameters(); DataTypeHelpers.TryFromTypeCached(originalConstructor.DeclaringType, allowCycles: true, out var res); if (res is StructuralDataType dataType) { var parameterMappings = EmptyReadOnlyCollection <string> .Instance; if (dataType.StructuralKind == StructuralDataTypeKinds.Entity) { var mappings = new List <string>(parameters.Length); var mappedCount = 0; for (var i = 0; i < parameters.Length; ++i) { var mapping = parameters[i].GetCustomAttribute <MappingAttribute>(inherit: false); if (mapping != null) { mappedCount++; mappings.Add(mapping.Uri); } } if (mappedCount != parameters.Length) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "There are '{0}' parameters in the constructor of '{1}' that do not have a mapping attributes. In order for type '{1}' to be a valid data model entity type, all of its constructors' parameters should be annotated with mapping attributes.", parameters.Length - mappedCount, originalConstructor.DeclaringType.ToCSharpStringPretty())); } if (mappings.Count > 0 && mappings[0] != null) { parameterMappings = mappings.AsReadOnly(); } } return(new DataModelConstructorInfoSlim(slimConstructor.DeclaringType, slimConstructor.ParameterTypes, parameterMappings)); } return(slimConstructor); }