protected ImmutableHashSet <IImportSatisfiabilityConstraint> GetMetadataViewConstraints(Type receivingType, bool importMany) { Requires.NotNull(receivingType, nameof(receivingType)); var result = ImmutableHashSet.Create <IImportSatisfiabilityConstraint>(); Type elementType = importMany ? PartDiscovery.GetElementTypeFromMany(receivingType) : receivingType; Type?metadataType = GetMetadataType(elementType); if (metadataType != null) { result = result.Add(ImportMetadataViewConstraint.GetConstraint(TypeRef.Get(metadataType, this.Resolver), this.Resolver)); } return(result); }
public bool IsSatisfiedBy(ExportDefinition exportDefinition) { Requires.NotNull(exportDefinition, nameof(exportDefinition)); // Fast path since immutable dictionaries are slow to enumerate. if (this.Requirements.IsEmpty) { return(true); } foreach (var entry in this.Requirements) { object value; if (!exportDefinition.Metadata.TryGetValue(entry.Key, out value)) { if (entry.Value.IsMetadataumValueRequired) { return(false); } else { // It's not required, and it's not present. No more validation necessary. continue; } } Type metadatumValueType = entry.Value.MetadatumValueType; if (value == null) { if (metadatumValueType.GetTypeInfo().IsValueType) { // A null reference for a value type is not a compatible match. return(false); } else { // Null is assignable to any reference type. continue; } } if (typeof(object[]).IsEquivalentTo(value.GetType()) && (entry.Value.MetadatumValueTypeRef.IsArray || (metadatumValueType.GetTypeInfo().IsGenericType&& typeof(IEnumerable <>).GetTypeInfo().IsAssignableFrom(metadatumValueType.GetTypeInfo().GetGenericTypeDefinition().GetTypeInfo())))) { // When ExportMetadata(IsMultiple=true), the value is an object[]. Check that each individual value is assignable. var receivingElementType = PartDiscovery.GetElementTypeFromMany(metadatumValueType).GetTypeInfo(); foreach (object item in (object[])value) { if (item == null) { if (receivingElementType.IsValueType) { // We cannot assign null to a struct type. return(false); } else { // Null can always be assigned to a reference type. continue; } } if (!receivingElementType.IsAssignableFrom(item.GetType().GetTypeInfo())) { return(false); } } // We're fully validated now. continue; } if (!metadatumValueType.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo())) { return(false); } } return(true); }
public ImportDefinitionBinding(ImportDefinition importDefinition, TypeRef composablePartType, ParameterRef importingConstructorParameter) : this( importDefinition, composablePartType, importingConstructorParameter, TypeRef.Get(importingConstructorParameter.Resolve().ParameterType, importingConstructorParameter.Resolver), TypeRef.Get(importDefinition.Cardinality == ImportCardinality.ZeroOrMore ? PartDiscovery.GetElementTypeFromMany(importingConstructorParameter.Resolve().ParameterType) : importingConstructorParameter.Resolve().ParameterType, importingConstructorParameter.Resolver)) { }
public ImportDefinitionBinding(ImportDefinition importDefinition, TypeRef composablePartType, MemberRef importingMember) : this( importDefinition, composablePartType, importingMember, TypeRef.Get(ReflectionHelpers.GetMemberType(importingMember.MemberInfo), importingMember.Resolver), TypeRef.Get(importDefinition.Cardinality == ImportCardinality.ZeroOrMore ? PartDiscovery.GetElementTypeFromMany(ReflectionHelpers.GetMemberType(importingMember.MemberInfo)) : ReflectionHelpers.GetMemberType(importingMember.MemberInfo), importingMember.Resolver)) { }