예제 #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)));
            }
            /// <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);
            }
예제 #3
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);
                }
            }
        }
예제 #4
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());
                }
            }
        }