private void ValidateContract(RelationMetadata metadata, IRelationListContract contract) { if (contract.ItemType == null) { this.ThrowContractException(metadata, "Item type cannot be null."); } else if (string.IsNullOrWhiteSpace(contract.ItemName)) { this.ThrowContractException(metadata, "Item name cannot be empty."); } else { Type enumerableType = typeof(IEnumerable <>).MakeGenericType(contract.ItemType); if (!enumerableType.IsAssignableFrom(metadata.Type)) { this.ThrowContractException(metadata, $"List of type '{metadata.Type.GetSanitizedName()}' cannot be converted to '{enumerableType.GetSanitizedName()}'."); } } if (contract.ReadIndex != null && !contract.ReadIndex.HasSignature(contract.ItemType, typeof(int))) { this.ThrowContractException(metadata, $"ReadIndex method must have signature '{contract.ItemType.GetSanitizedName()} (int)'."); } if (contract.WriteIndex != null && !contract.WriteIndex.HasSignature(typeof(void), typeof(int), contract.ItemType)) { this.ThrowContractException(metadata, $"WriteIndex method must have signature 'void (int, {contract.ItemType.GetSanitizedName()})'."); } }
private IRelationListContract GetListContract(RelationMetadata metadata) { IEnumerable <IRelationContractResolver> allResolvers = new[] { this.DefaultResolver }.Concat(this); IRelationListContract contract = allResolvers.Reverse().NotNull(cr => cr.GetListContract(metadata)).FirstOrDefault(); if (contract != null) { this.ValidateContract(metadata, contract); } return(contract); }
private RelationMetadata CreateItem(IMetadataBuilderContext context, RelationMetadata parent) { IRelationListContract contract = this.GetListContract(parent); if (contract == null) { return(null); } MetadataIdentity itemId = parent.Identity.Child(contract.ItemName ?? "Item"); RelationMetadata metadata = new RelationMetadata(itemId) { Parent = parent, Type = contract.ItemType, Flags = RelationMetadataFlags.Item | RelationMetadataFlags.Property, ReadIndex = contract.ReadIndex, WriteIndex = contract.WriteIndex, }; metadata.MemberOf = metadata; metadata.Item = this.CreateItem(context, metadata); metadata.Properties = this.CreateLazy(() => this.CreateProperties(context, metadata)); metadata.Annotations = this.CreateAnnotations(metadata).ToList(); if (this.IsMetadataRecursive(metadata)) { metadata.Flags |= RelationMetadataFlags.Recursive; } if (contract.ReadIndex != null) { metadata.Flags |= RelationMetadataFlags.Readable; } if (contract.WriteIndex != null) { metadata.Flags |= RelationMetadataFlags.Writable; } if (metadata.Item != null) { metadata.Flags |= RelationMetadataFlags.List; } context.AddMetadata <IRelationMetadata>(metadata); return(metadata); }