private static RuntimeImport CreateRuntimeImport(ImportDefinitionBinding importDefinitionBinding, IReadOnlyList <ExportDefinitionBinding> satisfyingExports, Resolver resolver) { Requires.NotNull(importDefinitionBinding, nameof(importDefinitionBinding)); Requires.NotNull(satisfyingExports, nameof(satisfyingExports)); var runtimeExports = satisfyingExports.Select(export => CreateRuntimeExport(export, resolver)).ToImmutableArray(); if (importDefinitionBinding.ImportingMemberRef != null) { return(new RuntimeImport( importDefinitionBinding.ImportingMemberRef, importDefinitionBinding.ImportingSiteTypeRef, importDefinitionBinding.ImportingSiteTypeWithoutCollectionRef, importDefinitionBinding.ImportDefinition.Cardinality, runtimeExports, PartCreationPolicyConstraint.IsNonSharedInstanceRequired(importDefinitionBinding.ImportDefinition), importDefinitionBinding.IsExportFactory, importDefinitionBinding.ImportDefinition.Metadata, importDefinitionBinding.ImportDefinition.ExportFactorySharingBoundaries)); } else { return(new RuntimeImport( importDefinitionBinding.ImportingParameterRef, importDefinitionBinding.ImportingSiteTypeRef, importDefinitionBinding.ImportingSiteTypeWithoutCollectionRef, importDefinitionBinding.ImportDefinition.Cardinality, runtimeExports, PartCreationPolicyConstraint.IsNonSharedInstanceRequired(importDefinitionBinding.ImportDefinition), importDefinitionBinding.IsExportFactory, importDefinitionBinding.ImportDefinition.Metadata, importDefinitionBinding.ImportDefinition.ExportFactorySharingBoundaries)); } }
private protected override IEnumerable <ExportInfo> GetExportsCore(ImportDefinition importDefinition) { var exports = this.composition.GetExports(importDefinition.ContractName); return (from export in exports let part = this.composition.GetPart(export) select this.CreateExport( importDefinition, export.Metadata, part.TypeRef, GetPartConstructedTypeRef(part, importDefinition.Metadata), part.SharingBoundary, !part.IsShared || PartCreationPolicyConstraint.IsNonSharedInstanceRequired(importDefinition), export.MemberRef)); }
private static IEnumerable <ComposedPartDiagnostic> FindLoops(IEnumerable <ComposedPart> parts) { Requires.NotNull(parts, nameof(parts)); var partByPartDefinition = parts.ToDictionary(p => p.Definition); var partByPartType = parts.ToDictionary(p => p.Definition.TypeRef); var partsAndDirectImports = new Dictionary <ComposedPart, IReadOnlyList <KeyValuePair <ImportDefinitionBinding, ComposedPart> > >(); foreach (var part in parts) { var directlyImportedParts = (from importAndExports in part.SatisfyingExports from export in importAndExports.Value let exportingPart = partByPartDefinition[export.PartDefinition] select new KeyValuePair <ImportDefinitionBinding, ComposedPart>(importAndExports.Key, exportingPart)).ToList(); partsAndDirectImports.Add(part, directlyImportedParts); } Func <Func <KeyValuePair <ImportDefinitionBinding, ComposedPart>, bool>, Func <ComposedPart, IEnumerable <ComposedPart> > > getDirectLinksWithFilter = filter => (part => partsAndDirectImports[part].Where(filter).Select(ip => ip.Value)); var visited = new HashSet <ComposedPart>(); // Find any loops of exclusively non-shared parts. var nonSharedPartsInLoops = new HashSet <ComposedPart>(); foreach (var part in partsAndDirectImports.Keys) { if (nonSharedPartsInLoops.Contains(part)) { // Don't check and report parts already detected to be involved in a loop. continue; } visited.Clear(); var path = PathExistsBetween(part, part, getDirectLinksWithFilter(ip => !ip.Key.IsExportFactory && (!ip.Value.Definition.IsShared || PartCreationPolicyConstraint.IsNonSharedInstanceRequired(ip.Key.ImportDefinition))), visited); if (!path.IsEmpty) { path = path.Push(part); nonSharedPartsInLoops.UnionWith(path); yield return(new ComposedPartDiagnostic(path, Strings.LoopBetweenNonSharedParts)); } } // Find loops even with shared parts where an importing constructor is involved. Func <KeyValuePair <ImportDefinitionBinding, ComposedPart>, bool> importingConstructorFilter = ip => !ip.Key.IsExportFactory && !ip.Key.IsLazy; foreach (var partAndImports in partsAndDirectImports) { var importingPart = partAndImports.Key; foreach (var import in partAndImports.Value) { var importDefinitionBinding = import.Key; var satisfyingPart = import.Value; if (importDefinitionBinding.ImportingParameterRef != null && importingConstructorFilter(import)) { visited.Clear(); var path = PathExistsBetween(satisfyingPart, importingPart, getDirectLinksWithFilter(importingConstructorFilter), visited); if (!path.IsEmpty) { path = path.Push(satisfyingPart).Push(partByPartType[importDefinitionBinding.ComposablePartTypeRef]); yield return(new ComposedPartDiagnostic(path, Strings.LoopInvolvingImportingCtorArgumentAndAllNonLazyImports)); } } } } }