private LoseNode ConvertToLoseNode(BlsPawn pawn) { var node = new LoseNode { Name = pawn.GetType().Name, ConnectionPoints = new List <LoseEnd>() }; List <PropertyInfo> properties = pawn.GetType().GetProperties().ToList(); foreach (PropertyInfo property in properties) { var propType = property.PropertyType; if (propType.BaseType != null && propType.BaseType.Name == typeof(Relation <>).Name && propType.IsGenericType && propType.GenericTypeArguments.Length == 1) { Type relatedType = propType.GenericTypeArguments[0]; object obj = pawn.GetType().GetProperty(property.Name)?.GetValue(pawn, null); if (obj != null) { Type objectType = obj.GetType().BaseType; if (objectType != null) { var mxProp = objectType.GetProperty("Multiplexer"); var minProp = objectType.GetProperty("MinConnections"); var maxProp = objectType.GetProperty("MaxConnections"); if (mxProp != null) { var min = minProp != null?minProp.GetValue(obj) : 0; var max = maxProp != null?maxProp.GetValue(obj) : int.MaxValue; string mxName = mxProp.GetValue(obj).ToString(); var end = new LoseEnd { ToName = relatedType.Name, Multiplexer = mxName, MinConnections = (int)min, MaxConnections = (int)max }; node.ConnectionPoints.Add(end); } } } } } return(node); }
private void ResolveRelations() { var nodes = new List <LoseNode>(); foreach (BlsPawn pawn in _pawns) { LoseNode node = ConvertToLoseNode(pawn); nodes.Add(node); } var allUniqueRelations = new HashSet <string>(); foreach (LoseNode node in nodes) { foreach (LoseEnd end in node.ConnectionPoints) { end.EncodedConnectionName = _storageNamingEncoder.EncodePawnRelationName(node.Name, end.ToName, end.Multiplexer); allUniqueRelations.Add(end.EncodedConnectionName); } var relationNames = node.ConnectionPoints.Select(n => n.EncodedConnectionName).ToArray(); if (relationNames.Length > relationNames.Distinct().Count()) { //todo: replace with custom exception throw new DuplicateRelationInPawnError($"Duplicate relation was found in {node.Name}. If you have more than one relation to a pawn, consider using a multiplexer"); } } foreach (LoseNode node in nodes) { foreach (LoseEnd end in node.ConnectionPoints) { var relation = new BlGraphRelation { SourceContainer = CompiledCollections.FirstOrDefault(c => c.BlContainerName == node.Name), TargetContainer = CompiledCollections.FirstOrDefault(c => c.BlContainerName == end.ToName), MaxConnections = end.MaxConnections, MinConnections = end.MinConnections, RelationName = _storageNamingEncoder.EncodePawnRelationName(node.Name, end.ToName, end.Multiplexer) }; CompiledRelations.Add(relation); } } }