/// <param name="buildStages">The sequence of build stages. See <see cref="Builder" /> for details.</param> /// <param name="patternTree">Build chain patterns tree used to find build actions to build a unit.</param> /// <param name="auxPatternTree">Additional build chain patterns tree, in opposite to <paramref name="patternTree"/> these patterns /// are passed to <paramref name="parentBuilders"/> if unit is being tried to build via parent builders.</param> /// <param name="parentBuilders"> /// If unit is not built and <paramref name="parentBuilders" /> are provided, tries to build a unit using /// parent builders one by one in the order they passed into the constructor. /// </param> public BuildSession(object[] buildStages, IBuildChainPattern patternTree, IBuildChainPattern?auxPatternTree, IBuilder[]?parentBuilders) { _buildStages = buildStages ?? throw new ArgumentNullException(nameof(buildStages)); if (buildStages.Length == 0) { throw new ArgumentException("Should contain at least one build stage", nameof(buildStages)); } if (buildStages.Any(stage => stage is null)) { throw new ArgumentException("Should not contain null values", nameof(buildStages)); } if (buildStages.Length != buildStages.Distinct().Count()) { throw new ArgumentException("Should not contain duplicate values", nameof(buildStages)); } if (parentBuilders?.Any(_ => _ is null) == true) { throw new ArgumentException("Should not contain null values", nameof(parentBuilders)); } _mainBuildChainPatternTree = patternTree ?? throw new ArgumentNullException(nameof(patternTree)); _auxPatternTree = auxPatternTree; _parentBuilders = parentBuilders; _buildChainList = new List <UnitId>(4); }
/// <summary> /// Overrides a previously registered <see cref="Treat{T}"/>. Mostly used in test environment to use mocks instead of real subsystems. /// </summary> public static TreatingTuner <T> TreatOverride <T>(this IBuildChainPattern pattern, object?tag = null) { if (pattern is null) { throw new ArgumentNullException(nameof(pattern)); } var newPatternMatcher = new SkipTillUnit(new UnitPattern(typeof(T), tag), WeightOf.BuildChainPattern.TargetUnit + WeightOf.UnitPattern.ExactTypePattern); var oldPatternMatcher = pattern.Children.Single(_ => _.Equals(newPatternMatcher)); pattern.Children.Remove(oldPatternMatcher); return(new TreatingTuner <T>(pattern.AddNode(newPatternMatcher))); }
/// <summary> /// Adds a <paramref name="node" /> to the <see cref="IBuildChainPattern.Children"/> collection of <paramref name="parentNode"/> /// if the node does not already exist. Returns the new node, or the existing node if the node already exists. /// </summary> /// <remarks>Call it first and then fill returned <see cref="IBuildChainPattern" /> with build actions or perform other needed actions due to /// it can return other instance of <see cref="IBuildChainPattern"/> then <paramref name="node"/>.</remarks> public static T GetOrAddNode <T>(this IBuildChainPattern parentNode, T node) where T : IBuildChainPattern { if (parentNode is null) { throw new ArgumentNullException(nameof(parentNode)); } if (node is null) { throw new ArgumentNullException(nameof(node)); } if (parentNode.Children.Contains(node)) { return((T)parentNode.Children.First(_ => _.Equals(node))); } parentNode.Children.Add(node); return(node); }
/// <summary> /// Adds the <paramref name="node" /> into <paramref name="parentNode" />. /// </summary> /// <exception cref="ArmatureException">A node is already in the tree</exception> public static T AddNode <T>(this IBuildChainPattern parentNode, T node, string?exceptionMessage = null) where T : IBuildChainPattern { if (parentNode is null) { throw new ArgumentNullException(nameof(parentNode)); } if (node is null) { throw new ArgumentNullException(nameof(node)); } if (parentNode.Children.Contains(node)) { throw new ArmatureException(exceptionMessage ?? $"Node '{node}' is already in the tree.") .AddData($"{nameof(parentNode)}", parentNode) .AddData($"{nameof(node)}", node); } parentNode.Children.Add(node); return(node); }
/// <summary> /// Adds a <see cref="IBuildAction" /> for a "to be built" unit which is matched by the branch of the pattern tree represented by this node /// with its parents. /// </summary> /// <param name="node"></param> /// <param name="buildAction">A build action.</param> /// <param name="buildStage">A build stage in which the build action is executed.</param> /// <returns>Returns 'this' in order to use fluent syntax</returns> public static IBuildChainPattern UseBuildAction(this IBuildChainPattern node, IBuildAction buildAction, object buildStage) { if (node is null) { throw new ArgumentNullException(nameof(node)); } if (buildAction is null) { throw new ArgumentNullException(nameof(buildAction)); } if (buildStage is null) { throw new ArgumentNullException(nameof(buildStage)); } var list = node.BuildActions.GetOrCreateValue(buildStage, () => new List <IBuildAction>()); if (!list.Contains(buildAction)) { list.Add(buildAction); } return(node); }
public static TreatingTuner Treat(this IBuildChainPattern pattern, Type type, object?tag = null) => new RootTuner(pattern).Treat(type, tag);
public static RootTuner Building <T>(this IBuildChainPattern pattern, object?tag = null) => new RootTuner(pattern).Building <T>(tag);
public static RootTuner Building(this IBuildChainPattern pattern, Type type, object?tag = null) => new RootTuner(pattern).Building(type, tag);
public static FinalTuner TreatAll(this IBuildChainPattern pattern) => new RootTuner(pattern).TreatAll();
public static TreatingTuner <T> TreatInheritorsOf <T>(this IBuildChainPattern pattern, object?tag = null) => new RootTuner(pattern).TreatInheritorsOf <T>(tag);
public static TreatingTuner TreatInheritorsOf(this IBuildChainPattern pattern, Type baseType, object?tag = null) => new RootTuner(pattern).TreatInheritorsOf(baseType, tag);
public static TreatingOpenGenericTuner TreatOpenGeneric(this IBuildChainPattern pattern, Type openGenericType, object?tag = null) => new RootTuner(pattern).TreatOpenGeneric(openGenericType, tag);
public RootTuner(IBuildChainPattern parentNode) : base(parentNode) { }
public CreationTuner(IBuildChainPattern parentNode, Type type, object?tag) : base(parentNode) { Type = type ?? throw new ArgumentNullException(nameof(type)); Tag = tag; }
public TreatingTuner(IBuildChainPattern parentNode) : base(parentNode) { }
public FinalTuner(IBuildChainPattern parentNode) : base(parentNode) { }