private void ValidateContract(RelationMetadata metadata, IRelationContract contract) { if (contract.ItemType == null) { throw MetadataBuilderException.InvalidContract(metadata, "Item type cannot be null."); } else if (string.IsNullOrWhiteSpace(contract.ItemName)) { throw MetadataBuilderException.InvalidContract(metadata, "Item name cannot be empty."); } else { Type enumerableType = typeof(IEnumerable <>).MakeGenericType(contract.ItemType); if (!enumerableType.IsAssignableFrom(metadata.Type)) { throw MetadataBuilderException.InvalidContract(metadata, $"List of type '{metadata.Type.GetSanitizedName()}' cannot be converted to '{enumerableType.GetSanitizedName()}'."); } } if (contract.ReadIndex != null && !contract.ReadIndex.HasSignature(contract.ItemType, typeof(int))) { throw MetadataBuilderException.InvalidContract(metadata, $"ReadIndex method must have signature '{contract.ItemType.GetSanitizedName()} (int)'."); } if (contract.WriteIndex != null && !contract.WriteIndex.HasSignature(typeof(void), typeof(int), contract.ItemType)) { throw MetadataBuilderException.InvalidContract(metadata, $"WriteIndex method must have signature 'void (int, {contract.ItemType.GetSanitizedName()})'."); } }
public TMetadata Lookup <TMetadata>(string name) where TMetadata : IMetadata { MetadataKey key = this.CreateKey <TMetadata>(name); ReaderWriterLockSlim slim = this.GetLock <TMetadata>(); try { slim.EnterReadLock(); if (this.entries.TryGetValue(key, out object value)) { return((TMetadata)value); } } catch (LockRecursionException ex) { throw MetadataBuilderException.NoRecursion <TMetadata>(name, ex); } finally { if (slim.IsReadLockHeld) { slim.ExitReadLock(); } } slim.EnterWriteLock(); try { MetadataIdentity identity = new MetadataIdentity(this, name); IRelationMetadata relation = this.GetCachedMetadata <IRelationMetadata>(name) ?? this.Store.RelationBuilder.GetMetadata(this, identity); if (relation == null) { return(default);