Exemple #1
0
        private CompositionResult TryPreviewImportsStateMachine(PartManager partManager,
                                                                ComposablePart part, AtomicComposition atomicComposition)
        {
            var result = CompositionResult.SucceededResult;

            if (partManager.State == ImportState.ImportsPreviewing)
            {
                // We shouldn't nomally ever hit this case but if we do
                // then we should just error with a cycle error.
                return(new CompositionResult(ErrorBuilder.CreatePartCycle(part)));
            }

            // Transition from NoImportsStatisified to ImportsPreviewed
            if (partManager.State == ImportState.NoImportsSatisfied)
            {
                partManager.State = ImportState.ImportsPreviewing;

                var requiredImports = part.ImportDefinitions.Where(IsRequiredImportForPreview);

                // If this atomicComposition gets rolledback for any reason we need to reset our state
                atomicComposition.AddRevertActionAllowNull(() => partManager.State = ImportState.NoImportsSatisfied);

                result = result.MergeResult(
                    this.TrySatisfyImportSubset(partManager, requiredImports, atomicComposition));

                if (!result.Succeeded)
                {
                    partManager.State = ImportState.NoImportsSatisfied;
                    return(result);
                }

                partManager.State = ImportState.ImportsPreviewed;
            }

            return(result);
        }
Exemple #2
0
        private CompositionResult TrySatisfyImportsStateMachine(PartManager partManager, ComposablePart part)
        {
            var result = CompositionResult.SucceededResult;

            while (partManager.State < ImportState.Composed)
            {
                var previousState = partManager.State;

                switch (partManager.State)
                {
                // "ed" states which represent a some sort of steady state and will
                // attempt to do a state transition
                case ImportState.NoImportsSatisfied:
                case ImportState.ImportsPreviewed:
                {
                    partManager.State = ImportState.PreExportImportsSatisfying;

                    var prereqImports = part.ImportDefinitions.Where(import => import.IsPrerequisite);
                    result = result.MergeResult(
                        this.TrySatisfyImportSubset(partManager, prereqImports, null));

                    partManager.State = ImportState.PreExportImportsSatisfied;
                    break;
                }

                case ImportState.PreExportImportsSatisfied:
                {
                    partManager.State = ImportState.PostExportImportsSatisfying;

                    var requiredImports = part.ImportDefinitions.Where(import => !import.IsPrerequisite);

                    result = result.MergeResult(
                        this.TrySatisfyImportSubset(partManager, requiredImports, null));

                    partManager.State = ImportState.PostExportImportsSatisfied;
                    break;
                }

                case ImportState.PostExportImportsSatisfied:
                {
                    partManager.State = ImportState.ComposedNotifying;

                    partManager.ClearSavedImports();
                    result = result.MergeResult(partManager.TryOnComposed());

                    partManager.State = ImportState.Composed;
                    break;
                }


                // "ing" states which represent some sort of cycle
                // These state should always return, error or not, instead of breaking
                case ImportState.ImportsPreviewing:
                {
                    // We shouldn't nomally ever hit this case but if we do
                    // then we should just error with a cycle error.
                    return(new CompositionResult(ErrorBuilder.CreatePartCycle(part)));
                }

                case ImportState.PreExportImportsSatisfying:
                case ImportState.PostExportImportsSatisfying:
                {
                    if (InPrerequisiteLoop())
                    {
                        return(result.MergeError(ErrorBuilder.CreatePartCycle(part)));
                    }
                    // Cycles in post export imports are allowed so just return in that case
                    return(result);
                }

                case ImportState.ComposedNotifying:
                {
                    // We are currently notifying so don't notify again just return
                    return(result);
                }
                }

                // if an error occured while doing a state transition
                if (!result.Succeeded)
                {
                    // revert to the previous state and return the error
                    partManager.State = previousState;
                    return(result);
                }
            }
            return(result);
        }