private string GetChangeRejectedExceptionMessage(ChangeRejectedException changeRejectedException)
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.AppendLine("Errors:");
            foreach (var error in changeRejectedException.Errors)
            {
                stringBuilder.AppendLine("     " + error.Description);
            }

            if (changeRejectedException.RootCauses.Count > 0)
            {
                stringBuilder.AppendLine("");
                stringBuilder.AppendLine("Root causes:");
                foreach (var exception in changeRejectedException.RootCauses)
                {
                    string rootCauseMessage = null;

                    var compositionException = exception as CompositionException;
                    if (compositionException != null)
                    {
                        rootCauseMessage = compositionException.Message;
                    }
                    else
                    {
                        rootCauseMessage = exception.Message;
                    }
                    stringBuilder.AppendLine("     " + rootCauseMessage);
                }
            }

            return(stringBuilder.ToString());
        }
 protected virtual void RecompositionException(ChangeRejectedException changeRejectedException)
 {
     if (throwOnRecompositionException)
     {
         throw changeRejectedException;
     }
 }
        internal static void PartDefinitionRejected(ComposablePartDefinition definition, ChangeRejectedException exception)
        {
            Assumes.NotNull(definition, exception);

            if (CompositionTraceSource.CanWriteWarning)
            {
                CompositionTraceSource.WriteWarning(CompositionTraceId.Rejection_DefinitionRejected, 
                                                    Strings.CompositionTrace_Rejection_DefinitionRejected, 
                                                    definition.GetDisplayName(), 
                                                    exception.Message);
            }
        }
        private void AddOrDeleteChanging(ComposablePartCatalogChangeEventArgs changeArgs, Action addDeleteAction, bool added)
        {
            bool changeException = false;
            ChangeRejectedException changeRejectedException = null;
            string failureDetails       = null;
            bool   recompositionSuccess = false;
            RecompositionEventReason recompositionEventReason = RecompositionEventReason.Deleted;

            try
            {
                Changing?.Invoke(this, changeArgs);
            }
            catch (ChangeRejectedException exc)
            {
                failureDetails  = GetChangeRejectedExceptionMessage(exc);
                changeException = true;
            }

            addDeleteAction();
            Changed?.Invoke(this, changeArgs);

            if (!changeException)
            {
                recompositionSuccess = true;
            }
            else
            {
                RecompositionException(changeRejectedException);
            }
            if (added)
            {
                recompositionEventReason = RecompositionEventReason.Added;
            }

            RecompositionAttemptEvent?.Invoke(this, new RecompositionAttemptEventArgs(recompositionSuccess, recompositionEventReason, failureDetails));
        }
        private bool DetermineRejection(ComposablePartDefinition definition, AtomicComposition parentAtomicComposition)
        {
            ChangeRejectedException exception = null;

            // if there is no active atomic composition and rejection is disabled, there's no need to do any of the below
            if (!EnsureRejection(parentAtomicComposition))
            {
                return(false);
            }

            using (var localAtomicComposition = new AtomicComposition(parentAtomicComposition))
            {
                // The part definition we're currently working on is treated optimistically
                // as if we know it hasn't been rejected.  This handles recursion, and if we
                // later decide that it has been rejected we'll discard all nested progress so
                // all side-effects of the mistake are erased.
                //
                // Note that this means that recursive failures that would be detected by the
                // import engine are not discovered by rejection currently.  Loops among
                // prerequisites, runaway import chains involving factories, and prerequisites
                // that cannot be fully satisfied still result in runtime errors.  Doing
                // otherwise would be possible but potentially expensive - and could be a v2
                // improvement if deemed worthwhile.
                UpdateAtomicCompositionQueryForPartEquals(localAtomicComposition,
                                                          definition, AtomicCompositionQueryState.TreatAsValidated);

                var newPart = definition.CreatePart();
                try
                {
                    _importEngine.PreviewImports(newPart, localAtomicComposition);

                    // Reuse the partially-fleshed out part the next time we need a shared
                    // instance to keep the expense of pre-validation to a minimum.  Note that
                    // _activatedParts holds references to both shared and non-shared parts.
                    // The non-shared parts will only be used for rejection purposes only but
                    // the shared parts will be handed out when requested via GetExports as
                    // well as be used for rejection purposes.
                    localAtomicComposition.AddCompleteActionAllowNull(() =>
                    {
                        using (_lock.LockStateForWrite())
                        {
                            if (!_activatedParts.ContainsKey(definition))
                            {
                                _activatedParts.Add(definition, new CatalogPart(newPart));
                                IDisposable newDisposablePart = newPart as IDisposable;
                                if (newDisposablePart != null)
                                {
                                    _partsToDispose.Add(newDisposablePart);
                                }
                            }
                        }
                    });

                    // Success! Complete any recursive work that was conditioned on this part's validation
                    localAtomicComposition.Complete();

                    return(false);
                }
                catch (ChangeRejectedException ex)
                {
                    exception = ex;
                }
            }

            // If we've reached this point then this part has been rejected so we need to
            // record the rejection in our parent composition or execute it immediately if
            // one doesn't exist.
            parentAtomicComposition.AddCompleteActionAllowNull(() =>
            {
                using (_lock.LockStateForWrite())
                {
                    _rejectedParts.Add(definition);
                }

                CompositionTrace.PartDefinitionRejected(definition, exception);
            });
            if (parentAtomicComposition != null)
            {
                UpdateAtomicCompositionQueryForPartEquals(parentAtomicComposition,
                                                          definition, AtomicCompositionQueryState.TreatAsRejected);
            }

            return(true);
        }
Exemplo n.º 6
0
        internal static void PartDefinitionRejected(ComposablePartDefinition definition, ChangeRejectedException exception)
        {
            if (definition == null)
            {
                throw new ArgumentNullException(nameof(definition));
            }

            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }


            if (CompositionTraceSource.CanWriteWarning)
            {
                CompositionTraceSource.WriteWarning(CompositionTraceId.Rejection_DefinitionRejected,
                                                    SR.CompositionTrace_Rejection_DefinitionRejected,
                                                    definition.GetDisplayName(),
                                                    exception.Message);
            }
        }
Exemplo n.º 7
0
        internal static void PartDefinitionRejected(ComposablePartDefinition definition, ChangeRejectedException exception)
        {
            Assumes.NotNull(definition, exception);

            if (CompositionTraceSource.CanWriteWarning)
            {
                CompositionTraceSource.WriteWarning(CompositionTraceId.Rejection_DefinitionRejected,
                                                    Strings.CompositionTrace_Rejection_DefinitionRejected,
                                                    definition.GetDisplayName(),
                                                    exception.Message);
            }
        }