public Delegate?CreateDelegate(Type delegateType) { Requires.NotNull(delegateType, nameof(delegateType)); if (delegateType == typeof(Delegate) || delegateType == typeof(MulticastDelegate)) { delegateType = ReflectionHelpers.GetContractTypeForDelegate(this.method); } try { return(this.method.CreateDelegate(delegateType, this.target)); } catch (ArgumentException) { // Bind failure occurs return null; return(null); } }
protected override ComposablePartDefinition?CreatePart(Type partType, bool typeExplicitlyRequested) { Requires.NotNull(partType, nameof(partType)); var partTypeInfo = partType.GetTypeInfo(); // We want to ignore abstract classes, but we want to consider static classes. // Static classes claim to be both abstract and sealed. So to ignore just abstract // ones, we check that they are not sealed. if (partTypeInfo.IsAbstract && !partTypeInfo.IsSealed) { return(null); } BindingFlags everythingLocal = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; BindingFlags instanceLocal = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; // If the type is abstract only find local static exports var exportBindingFlags = everythingLocal; if (partTypeInfo.IsAbstract) { exportBindingFlags &= ~BindingFlags.Instance; } var declaredMethods = partType.GetMethods(exportBindingFlags); // methods can only export, not import var declaredProperties = partType.GetProperties(everythingLocal); var declaredFields = partType.GetFields(everythingLocal); var allLocalMembers = declaredMethods.Concat <MemberInfo>(declaredProperties).Concat(declaredFields); var exportingMembers = from member in allLocalMembers from export in member.GetAttributes <ExportAttribute>() select new KeyValuePair <MemberInfo, ExportAttribute>(member, export); var exportedTypes = from export in partTypeInfo.GetAttributes <ExportAttribute>() select new KeyValuePair <MemberInfo, ExportAttribute>(partTypeInfo, export); var inheritedExportedTypes = from baseTypeOrInterface in partType.GetInterfaces().Concat(partType.EnumTypeAndBaseTypes().Skip(1)) where baseTypeOrInterface != typeof(object) from export in baseTypeOrInterface.GetTypeInfo().GetAttributes <InheritedExportAttribute>() select new KeyValuePair <MemberInfo, ExportAttribute>(baseTypeOrInterface.GetTypeInfo(), export); var exportsByMember = (from export in exportingMembers.Concat(exportedTypes).Concat(inheritedExportedTypes) group export.Value by export.Key into exportsByType select exportsByType).Select(g => new KeyValuePair <MemberInfo, ExportAttribute[]>(g.Key, g.ToArray())).ToArray(); if (exportsByMember.Length == 0) { return(null); } // Check for PartNotDiscoverable only after we've established it's an interesting part. // This optimizes for the fact that most types have no exports, in which case it's not a discoverable // part anyway. Checking for the PartNotDiscoverableAttribute first, which is rarely defined, // doesn't usually pay for itself in terms of short-circuiting. But it does add an extra // attribute to look for that we don't need to find for all the types that have no export attributes either. if (!typeExplicitlyRequested && partTypeInfo.IsAttributeDefined <PartNotDiscoverableAttribute>()) { return(null); } foreach (var exportingMember in exportsByMember) { this.ThrowOnInvalidExportingMember(exportingMember.Key); } TypeRef partTypeRef = TypeRef.Get(partType, this.Resolver); Type? partTypeAsGenericTypeDefinition = partTypeInfo.IsGenericType ? partType.GetGenericTypeDefinition() : null; // Collect information for all imports. var imports = ImmutableList.CreateBuilder <ImportDefinitionBinding>(); this.AddImportsFromMembers(declaredProperties, declaredFields, partTypeRef, imports); Type?baseType = partTypeInfo.BaseType; while (baseType != null && baseType != typeof(object)) { this.AddImportsFromMembers(baseType.GetProperties(instanceLocal), baseType.GetFields(instanceLocal), partTypeRef, imports); baseType = baseType.GetTypeInfo().BaseType; } var partCreationPolicy = CreationPolicy.Any; var partCreationPolicyAttribute = partTypeInfo.GetFirstAttribute <PartCreationPolicyAttribute>(); if (partCreationPolicyAttribute != null) { partCreationPolicy = (CreationPolicy)partCreationPolicyAttribute.CreationPolicy; } var allExportsMetadata = ImmutableDictionary.CreateRange(PartCreationPolicyConstraint.GetExportMetadata(partCreationPolicy)); var inheritedExportContractNamesFromNonInterfaces = ImmutableHashSet.CreateBuilder <string>(); var exportDefinitions = ImmutableList.CreateBuilder <KeyValuePair <MemberInfo, ExportDefinition> >(); foreach (var export in exportsByMember) { var memberExportMetadata = allExportsMetadata.AddRange(GetExportMetadata(export.Key)); if (export.Key is MethodInfo method) { var exportAttributes = export.Value; if (exportAttributes.Any()) { foreach (var exportAttribute in exportAttributes) { Type exportedType = exportAttribute.ContractType ?? ReflectionHelpers.GetContractTypeForDelegate(method); string contractName = string.IsNullOrEmpty(exportAttribute.ContractName) ? GetContractName(exportedType) : exportAttribute.ContractName; var exportMetadata = memberExportMetadata .Add(CompositionConstants.ExportTypeIdentityMetadataName, ContractNameServices.GetTypeIdentity(exportedType)); var exportDefinition = new ExportDefinition(contractName, exportMetadata); exportDefinitions.Add(new KeyValuePair <MemberInfo, ExportDefinition>(export.Key, exportDefinition)); } } } else { MemberInfo exportingTypeOrPropertyOrField = export.Key; Verify.Operation(export.Key is TypeInfo || !partTypeInfo.IsGenericTypeDefinition, Strings.ExportsOnMembersNotAllowedWhenDeclaringTypeGeneric); Type exportSiteType = ReflectionHelpers.GetMemberType(exportingTypeOrPropertyOrField); foreach (var exportAttribute in export.Value) { Type exportedType = exportAttribute.ContractType ?? partTypeAsGenericTypeDefinition ?? exportSiteType; string contractName = string.IsNullOrEmpty(exportAttribute.ContractName) ? GetContractName(exportedType) : exportAttribute.ContractName; if (export.Key is TypeInfo && exportAttribute is InheritedExportAttribute) { if (inheritedExportContractNamesFromNonInterfaces.Contains(contractName)) { // We already have an export with this contract name on this type (from a more derived type) // using InheritedExportAttribute. continue; } if (!((TypeInfo)export.Key).IsInterface) { inheritedExportContractNamesFromNonInterfaces.Add(contractName); } } var exportMetadata = memberExportMetadata .Add(CompositionConstants.ExportTypeIdentityMetadataName, ContractNameServices.GetTypeIdentity(exportedType)); var exportDefinition = new ExportDefinition(contractName, exportMetadata); exportDefinitions.Add(new KeyValuePair <MemberInfo, ExportDefinition>(export.Key, exportDefinition)); } } } MethodInfo?onImportsSatisfied = null; if (typeof(IPartImportsSatisfiedNotification).IsAssignableFrom(partType)) { onImportsSatisfied = OnImportsSatisfiedMethodInfo; } var importingConstructorParameters = ImmutableList.CreateBuilder <ImportDefinitionBinding>(); var importingCtor = GetImportingConstructor <ImportingConstructorAttribute>(partType, publicOnly: false); if (importingCtor != null) // some parts have exports merely for metadata -- they can't be instantiated { foreach (var parameter in importingCtor.GetParameters()) { var import = this.CreateImport(parameter); if (import.ImportDefinition.Cardinality == ImportCardinality.ZeroOrMore) { Verify.Operation(PartDiscovery.IsImportManyCollectionTypeCreateable(import), Strings.CollectionMustBePublicAndPublicCtorWhenUsingImportingCtor); } importingConstructorParameters.Add(import); } } var partMetadata = ImmutableDictionary.CreateBuilder <string, object?>(); foreach (var partMetadataAttribute in partTypeInfo.GetAttributes <PartMetadataAttribute>()) { partMetadata[partMetadataAttribute.Name] = partMetadataAttribute.Value; } var exportsOnType = exportDefinitions.Where(kv => kv.Key is TypeInfo).Select(kv => kv.Value).ToArray(); var exportsOnMembers = (from kv in exportDefinitions where !(kv.Key is TypeInfo) group kv.Value by kv.Key into byMember select byMember).ToDictionary(g => MemberRef.Get(g.Key, this.Resolver), g => (IReadOnlyCollection <ExportDefinition>)g.ToArray()); var assemblyNamesForMetadataAttributes = ImmutableHashSet.CreateBuilder <AssemblyName>(ByValueEquality.AssemblyName); foreach (var export in exportsByMember) { GetAssemblyNamesFromMetadataAttributes <MetadataAttributeAttribute>(export.Key, assemblyNamesForMetadataAttributes); } return(new ComposablePartDefinition( TypeRef.Get(partType, this.Resolver), partMetadata.ToImmutable(), exportsOnType, exportsOnMembers, imports.ToImmutable(), partCreationPolicy != CreationPolicy.NonShared ? string.Empty : null, MethodRef.Get(onImportsSatisfied, this.Resolver), MethodRef.Get(importingCtor, this.Resolver), importingCtor != null ? importingConstructorParameters.ToImmutable() : null, // some MEF parts are only for metadata partCreationPolicy, assemblyNamesForMetadataAttributes, partCreationPolicy != CreationPolicy.NonShared)); }