| File: MS\Internal\Documents\Application\ChainOfDependencies.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationUI\PresentationUI.csproj (PresentationUI) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // Description: // A Generic that provides user with the ability to chain dependent objects // of a shared base type and perform actions on them in order of dependency. namespace MS.Internal.Documents.Application { /// <summary> /// A Generic that provides user with the ability to chain dependent objects /// of a shared base type and perform actions on them in order of dependency. /// </summary> /// <remarks> /// This is different from the chain of responsiblity in the following ways: /// /// - Order of execution in the chain can be inversed by calling LastToFirst. /// - The same operation is performed on each member once. /// /// This class has many methods which are intentionaly recursive. There is /// currently no validation to prevent cyclic dependencies. As the chain is /// currently fixed at compile time there is no need; StackOverFlowException /// durring testing is fine. /// </remarks> /// <typeparam name="T">A type common to all in the chain.</typeparam> internal static class ChainOfDependencies<T> where T : IChainOfDependenciesNode<T> { #region Internal Methods //-------------------------------------------------------------------------- // Internal Methods //-------------------------------------------------------------------------- /// <summary> /// Gets the last member in the chain. (The one with no dependencies.) /// </summary> /// <param name="member">The current member.</param> /// <returns>The last member in the chain. (The one with no dependencies.) /// </returns> internal static T GetLast(T member) { T last = member; if (member.Dependency != null) { last = GetLast(member.Dependency); } return last; } /// <summary> /// Will perform the action from the member with no dependencies to the most /// dependent member. /// </summary> /// <param name="member">The member on which to perform the action.</param> /// <param name="action">The action to perform on the member.</param> /// <returns>Returns true if all the actions returned true.</returns> internal static bool OrderByLeastDependent( T member, ChainOfDependencies<T>.Action action) { bool satisfied = true; T nextInChain = member.Dependency; if (nextInChain != null) { satisfied = OrderByLeastDependent(nextInChain, action); } if (satisfied) { satisfied = action(member); } else { Trace.SafeWrite( Trace.File, "Dependency for {0}#{1} was not satisfied skipping action.", member.GetType(), member.GetHashCode()); } return satisfied; } /// <summary> /// Will perform the action from most dependent to not dependent. /// </summary> /// <param name="member">The member on which to perform the action.</param> /// <param name="action">The action to perform on the member.</param> /// <returns>Returns true if the all the actions returned true.</returns> internal static bool OrderByMostDependent( T member, ChainOfDependencies<T>.Action action) { bool satisfied = action(member); T nextInChain = member.Dependency; if (satisfied) { if (nextInChain != null) { satisfied = OrderByMostDependent(nextInChain, action); } } else { Trace.SafeWrite( Trace.File, "Dependency for {0}#{1} was not satisfied skipping action.", member.GetType(), member.GetHashCode()); } return satisfied; } #endregion Internal Methods #region Internal Delegates //-------------------------------------------------------------------------- // Internal Delegates //-------------------------------------------------------------------------- /// <summary> /// An action to perform on a ChainOfDependencies member. /// </summary> /// <param name="member">The member on which to perform the action.</param> /// <returns>True if the dependency was satisfied.</returns> internal delegate bool Action(T member); #endregion Internal Delegates } }