private void SearchNode(TargetTypeGraph graph, Type node, int level) { if (level > _configuration.MaxRecursion) { throw new SanityException($"While looking for a connected graph we went over the recursion limit {level}."); } if (!graph.AddNode(node)) { return; } foreach (var property in node.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var propertyType = property.PropertyType; if (_configuration.IsAllowedForColumn(propertyType)) { graph.AddProperty(node, property); } else if (_configuration.ShouldMediateTargetProperty(property)) { graph.AddEdge(node, property); SearchNode(graph, propertyType, level + 1); } else { // ignore } } }
/// <summary> /// Depth first search. /// </summary> public TargetTypeGraph SearchGraph(Type origin) { var graph = new TargetTypeGraph(); if (_configuration.IsAllowedForColumn(origin)) { return(graph); } SearchNode(graph, origin, 0); return(graph); }
public MediatorMapper CreateMediatorTypes(TargetTypeGraph graph) { var assemblyName = new AssemblyName(_assemblyName); var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect); var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); var targetToMediators = new Dictionary <Type, TypeBuilder>(); foreach (var node in graph.Nodes) { var targetType = node.Type; var mediatorTypeName = targetType.Namespace + ".«" + targetType.Name + "»"; // TODO: Does it need to be public? var typeBuilder = moduleBuilder.DefineType(mediatorTypeName, TypeAttributes.Public); typeBuilder.DefineDefaultConstructor(); foreach (var columnMember in node.ColumnMembers) { typeBuilder.DefineMediatorColumnMember(columnMember); } targetToMediators.Add(targetType, typeBuilder); } foreach (var edge in graph.Edges) { var fromNodeTypeBuilder = targetToMediators[edge.From.Type]; fromNodeTypeBuilder.DefineMediatorMember(edge.Member, targetToMediators); } var mediatorMaps = targetToMediators.Select(targetToMediator => { var targetType = targetToMediator.Key; var mediatorType = targetToMediator.Value.CreateType(); return(new MediatorTypeMap(targetType, mediatorType)); }); return(new MediatorMapper(mediatorMaps)); }