Example #1
0
        internal static Assignability IsAssignableTo(ImportDefinitionBinding import, ExportDefinitionBinding export)
        {
            Requires.NotNull(import, nameof(import));
            Requires.NotNull(export, nameof(export));

            var receivingTypeRef = import.ImportingSiteElementTypeRef;
            var exportingTypeRef = export.ExportedValueTypeRef;

            if (exportingTypeRef.IsGenericTypeDefinition && receivingTypeRef.IsGenericType)
            {
                exportingTypeRef = exportingTypeRef.MakeGenericTypeRef(receivingTypeRef.GenericTypeArguments);
            }

            // Quick assignability check to attempt to exit early if assignable, otherwise use the slower methods
            if (receivingTypeRef.IsAssignableFrom(exportingTypeRef))
            {
                return(Assignability.Definitely);
            }
            else if (typeof(Delegate).GetTypeInfo().IsAssignableFrom(exportingTypeRef.ResolvedType) && typeof(Delegate).GetTypeInfo().IsAssignableFrom(receivingTypeRef.ResolvedType))
            {
                // Delegates of varying types may be assigned to each other.
                // For example Action<object, EventArgs> can be assigned to EventHandler.
                // The simplest way to test for it is to ask the CLR to do it.
                // http://stackoverflow.com/questions/23075298/how-to-detect-compatibility-between-delegate-types/23088194#23088194
                try
                {
                    Assumes.NotNull(export.ExportingMember);
                    ((MethodInfo)export.ExportingMember).CreateDelegate(receivingTypeRef.ResolvedType, null);
                    return(Assignability.Definitely);
                }
                catch (ArgumentException)
                {
                    return(Assignability.DefinitelyNot);
                }
                catch (TargetParameterCountException)
                {
                    return(Assignability.DefinitelyNot);
                }
            }
            else
            {
                bool valueTypeKnownExactly =
                    export.ExportingMemberRef == null || // When [Export] appears on the type itself, we instantiate that exact type.
                    exportingTypeRef.ResolvedType.GetTypeInfo().IsSealed;
                if (valueTypeKnownExactly)
                {
                    // There is no way that an exported value can implement the required types to make it assignable.
                    return(Assignability.DefinitelyNot);
                }

                if (receivingTypeRef.ResolvedType.GetTypeInfo().IsInterface || exportingTypeRef.ResolvedType.GetTypeInfo().IsAssignableFrom(receivingTypeRef.ResolvedType))
                {
                    // The actual exported value at runtime *may* be a derived type that *is* assignable to the import site.
                    return(Assignability.Maybe);
                }

                return(Assignability.DefinitelyNot);
            }
        }
Example #2
0
        private static RuntimeExport CreateRuntimeExport(ExportDefinitionBinding exportDefinitionBinding, Resolver resolver)
        {
            Requires.NotNull(exportDefinitionBinding, nameof(exportDefinitionBinding));
            Requires.NotNull(resolver, nameof(resolver));

            var partDefinitionType = exportDefinitionBinding.PartDefinition.TypeRef.Resolve();

            return(CreateRuntimeExport(
                       exportDefinitionBinding.ExportDefinition,
                       partDefinitionType,
                       exportDefinitionBinding.ExportingMemberRef,
                       resolver));
        }
Example #3
0
        private static string GetDiagnosticLocation(ExportDefinitionBinding export)
        {
            Requires.NotNull(export, nameof(export));

            if (export.ExportingMemberRef != null)
            {
                return(string.Format(
                           CultureInfo.CurrentCulture,
                           "{0}.{1}",
                           export.PartDefinition.Type.FullName,
                           export.ExportingMember.Name));
            }
            else
            {
                return(export.PartDefinition.Type.FullName);
            }
        }
Example #4
0
        private static string?GetDiagnosticLocation(ExportDefinitionBinding export)
        {
            Requires.NotNull(export, nameof(export));

            if (export.ExportingMemberRef != null)
            {
                return(string.Format(
                           CultureInfo.CurrentCulture,
                           Strings.TypeNameWithAssemblyLocation,
                           export.PartDefinition.Type.FullName,
                           export.ExportingMemberRef.Name,
                           export.PartDefinition.Type.GetTypeInfo().Assembly.FullName));
            }
            else
            {
                return(export.PartDefinition.Type.FullName);
            }
        }