Esempio n. 1
0
            public override bool Equals(IReadOnlyDictionary <string, object> x, IReadOnlyDictionary <string, object> y)
            {
                if (object.ReferenceEquals(x, y))
                {
                    return(true);
                }

                // Be sure we're comparing TypeRefs instead of resolved Types to avoid loading assemblies unnecessarily.
                return(base.Equals(LazyMetadataWrapper.TryUnwrap(x), LazyMetadataWrapper.TryUnwrap(y)));
            }
Esempio n. 2
0
        protected void Write(IReadOnlyDictionary <string, object> metadata)
        {
            using (this.Trace("Metadata"))
            {
                this.WriteCompressedUInt((uint)metadata.Count);

                // Special case certain values to avoid defeating lazy load later.
                // Check out the ReadMetadata below, how it wraps the return value.
                var serializedMetadata = new LazyMetadataWrapper(metadata.ToImmutableDictionary(), LazyMetadataWrapper.Direction.ToSubstitutedValue, this.Resolver);
                foreach (var entry in serializedMetadata)
                {
                    this.Write(entry.Key);
                    this.WriteObject(entry.Value);
                }
            }
        }
            /// <summary>
            /// Gets the constructed type (non generic type definition) for a part.
            /// </summary>
            private static Reflection.TypeRef GetPartConstructedTypeRef(RuntimeComposition.RuntimePart part, IReadOnlyDictionary <string, object?> importMetadata)
            {
                Requires.NotNull(part, nameof(part));
                Requires.NotNull(importMetadata, nameof(importMetadata));

                if (part.TypeRef.IsGenericTypeDefinition)
                {
                    var    bareMetadata = LazyMetadataWrapper.TryUnwrap(importMetadata);
                    object?typeArgsObject;
                    if (bareMetadata.TryGetValue(CompositionConstants.GenericParametersMetadataName, out typeArgsObject) && typeArgsObject is object)
                    {
                        IEnumerable <TypeRef> typeArgs = typeArgsObject is LazyMetadataWrapper.TypeArraySubstitution
                            ? ((LazyMetadataWrapper.TypeArraySubstitution)typeArgsObject).TypeRefArray
                            : ReflectionHelpers.TypesToTypeRefs((Type[])typeArgsObject, part.TypeRef.Resolver);

                        return(part.TypeRef.MakeGenericTypeRef(typeArgs.ToImmutableArray()));
                    }
                }

                return(part.TypeRef);
            }
Esempio n. 4
0
        protected void Write(IReadOnlyDictionary <string, object?> metadata)
        {
            using (this.Trace("Metadata"))
            {
                this.WriteCompressedUInt((uint)metadata.Count);

                // Special case certain values to avoid defeating lazy load later.
                // Check out the ReadMetadata below, how it wraps the return value.
                IReadOnlyDictionary <string, object?> serializedMetadata;

                // Unwrap the metadata if its an instance of LazyMetaDataWrapper, the wrapper may end up
                // implicitly resolving TypeRefs to Types which is undesirable.
                metadata = LazyMetadataWrapper.TryUnwrap(metadata);

                serializedMetadata = new LazyMetadataWrapper(metadata.ToImmutableDictionary(), LazyMetadataWrapper.Direction.ToSubstitutedValue, this.Resolver);

                foreach (var entry in serializedMetadata)
                {
                    this.Write(entry.Key);
                    this.WriteObject(entry.Value);
                }
            }
        }
Esempio n. 5
0
        internal static void GetInputAssembliesFromMetadata(ISet <AssemblyName> assemblies, IReadOnlyDictionary <string, object> metadata)
        {
            Requires.NotNull(assemblies, nameof(assemblies));
            Requires.NotNull(metadata, nameof(metadata));

            // Get the underlying metadata (should not load the assembly)
            metadata = LazyMetadataWrapper.TryUnwrap(metadata);
            foreach (var value in metadata.Values.Where(v => v != null))
            {
                var valueAsType = value as Type;
                var valueType   = value.GetType();

                // Check lazy metadata first, then try to get the type data from the value (if not lazy)
                if (typeof(LazyMetadataWrapper.Enum32Substitution) == valueType)
                {
                    ((LazyMetadataWrapper.Enum32Substitution)value).EnumType.GetInputAssemblies(assemblies);
                }
                else if (typeof(LazyMetadataWrapper.TypeSubstitution) == valueType)
                {
                    ((LazyMetadataWrapper.TypeSubstitution)value).TypeRef.GetInputAssemblies(assemblies);
                }
                else if (typeof(LazyMetadataWrapper.TypeArraySubstitution) == valueType)
                {
                    foreach (var typeRef in ((LazyMetadataWrapper.TypeArraySubstitution)value).TypeRefArray)
                    {
                        typeRef.GetInputAssemblies(assemblies);
                    }
                }
                else if (valueAsType != null)
                {
                    GetTypeAndBaseTypeAssemblies(assemblies, valueAsType);
                }
                else if (value.GetType().IsArray)
                {
                    // If the value is an array, we should determine the assemblies of each item.
                    var array = value as object[];
                    if (array != null)
                    {
                        foreach (var obj in array.Where(o => o != null))
                        {
                            // Check to see if the value is a type. We should get the assembly from
                            // the value if that's the case.
                            var objType = obj as Type;
                            if (objType != null)
                            {
                                GetTypeAndBaseTypeAssemblies(assemblies, objType);
                            }
                            else
                            {
                                GetTypeAndBaseTypeAssemblies(assemblies, obj.GetType());
                            }
                        }
                    }
                    else
                    {
                        // Array is full of primitives. We can just use value's assembly data
                        GetTypeAndBaseTypeAssemblies(assemblies, value.GetType());
                    }
                }
                else
                {
                    GetTypeAndBaseTypeAssemblies(assemblies, value.GetType());
                }
            }
        }
Esempio n. 6
0
 protected virtual LazyMetadataWrapper Clone(LazyMetadataWrapper oldVersion, IReadOnlyDictionary <string, object> newMetadata)
 {
     return(new LazyMetadataWrapper(newMetadata.ToImmutableDictionary(), oldVersion.direction, this.resolver));
 }
Esempio n. 7
0
        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 (!LazyMetadataWrapper.TryGetLoadSafeValueTypeRef(exportDefinition.Metadata, entry.Key, this.Resolver, out value))
                {
                    if (entry.Value.IsMetadataumValueRequired)
                    {
                        return(false);
                    }
                    else
                    {
                        // It's not required, and it's not present. No more validation necessary.
                        continue;
                    }
                }

                TypeRef metadatumValueTypeRef = entry.Value.MetadatumValueTypeRef;
                if (value == null)
                {
                    if (metadatumValueTypeRef.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 (value is TypeRef valueTypeRef)
                {
                    if (!metadatumValueTypeRef.ElementTypeRef.IsAssignableFrom(valueTypeRef.ElementTypeRef))
                    {
                        return(false);
                    }

                    continue;
                }

                if (value is TypeRef[] valueTypeRefArray && metadatumValueTypeRef.ElementTypeRef != metadatumValueTypeRef)
                {
                    var receivingElementTypeRef = metadatumValueTypeRef.ElementTypeRef;
                    foreach (var item in valueTypeRefArray)
                    {
                        if (item == null)
                        {
                            if (receivingElementTypeRef.IsValueType)
                            {
                                return(false);
                            }
                            else
                            {
                                continue;
                            }
                        }

                        if (!receivingElementTypeRef.IsAssignableFrom(item))
                        {
                            return(false);
                        }
                    }

                    continue;
                }
            }

            return(true);
        }