private static PropertyInfo RetrieveSourceProperty(ConnectionAttribute a, Control c) { PropertyInfo piSource = null; String prop = a.ControlProperty; try { piSource = c.GetType().GetProperty(prop); } catch (Exception ex) { throw new InitializerException( new StringBuilder("Source property '"). Append(prop). Append("' not found").ToString(), ex); } if (piSource == null) { throw new InitializerException( new StringBuilder("Source property '"). Append(prop). Append("' not found").ToString()); } return(piSource); }
public T CreateDataItem <T>(Control control) where T : new() { FieldInfo[] fis = control.GetType().GetFields( BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); T t = new T(); foreach (FieldInfo fi in fis) { ConnectionAttribute a = (ConnectionAttribute)Attribute.GetCustomAttribute(fi, typeof(ConnectionAttribute)); if (a != null && a.ConnectedType.Equals(t.GetType())) { Control c = (Control)fi.GetValue(control); if ((c == null) || (!c.Visible && !a.CopyOnInvisible()) || (!c.Enabled && !a.CopyOnDisabled())) { if (a.DefaultValueProvider != null) { CopyDefaultValue <T>(t, a); } } else { CopyProperty <T>(t, a, c); } } } return(t); }
public void ConfigureControl(Control control, Object dataItem) { FieldInfo[] fis = control.GetType().GetFields( BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo fi in fis) { ConnectionAttribute a = (ConnectionAttribute)Attribute.GetCustomAttribute(fi, typeof(ConnectionAttribute)); if (a != null && a.ConnectedType.Equals(dataItem.GetType())) { Control c = (Control)fi.GetValue(control); if ((c == null) || (!c.Visible && !a.CopyOnInvisible()) || (!c.Enabled && !a.CopyOnDisabled())) { continue; } else { CopyProperty(dataItem, a, c); } } } }
private void AddConnectionTreeViewContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e) { try { // dynamically create a drop down list of all connections available in plugins addConnectionToolStripMenuItem.DropDownItems.Clear(); List <Type> connectionTypes = CoreUtility.GetInterfaceImplementorsWithAttribute(typeof(IConnection), typeof(ConnectionAttribute)); foreach (Type connectionType in connectionTypes) { ConnectionAttribute connectionAttribute = (ConnectionAttribute)Attribute.GetCustomAttribute(connectionType, typeof(ConnectionAttribute)); ToolStripMenuItem addConnectionToolStripMenuItem = new ToolStripMenuItem(connectionType.Name) { ImageScaling = ToolStripItemImageScaling.None, Tag = connectionType }; addConnectionToolStripMenuItem.Click += AddConnectionToolStripMenuItem_Click; addConnectionToolStripMenuItem.Text = connectionAttribute.DisplayName; addConnectionToolStripMenuItem.ToolTipText = connectionAttribute.Description; addConnectionToolStripMenuItem.Image = connectionAttribute.GetIcon(connectionType.Assembly); this.addConnectionToolStripMenuItem.DropDownItems.Add(addConnectionToolStripMenuItem); } addConnectionToolStripMenuItem.Enabled = addConnectionToolStripMenuItem.DropDownItems.Count > 0; } catch (Exception ex) { ApplicationState.Default.RaiseNotification(new NotificationEventArgs(NotificationType.Error, ex.Message, ex)); } }
private static PropertyInfo RetrieveTargetProperty <T>(T t, ConnectionAttribute a) where T : new() { PropertyInfo piTarget = null; String prop = a.DataItemProperty; try { piTarget = t.GetType().GetProperty(prop); } catch (Exception ex) { throw new InitializerException( new StringBuilder("Target property '"). Append(prop). Append("' not found").ToString(), ex); } if (piTarget == null) { throw new InitializerException( new StringBuilder("Target property '"). Append(prop). Append("' not found").ToString()); } return(piTarget); }
private static void CopyProperty(Object dataItem, ConnectionAttribute a, Control c) { PropertyInfo piSource = null; PropertyInfo piTarget = null; String prop = a.DataItemProperty; try { piSource = dataItem.GetType().GetProperty(prop); } catch (Exception ex) { throw new InitializerException( new StringBuilder("Source property '"). Append(prop). Append("' not found").ToString(), ex); } if (piSource == null) { throw new InitializerException( new StringBuilder("Source property '"). Append(prop). Append("' not found").ToString()); } prop = a.ControlProperty; try { piTarget = c.GetType().GetProperty(prop); } catch (Exception ex) { throw new InitializerException( new StringBuilder("Target property '"). Append(prop). Append("' not found").ToString(), ex); } if (piTarget == null) { throw new InitializerException( new StringBuilder("Target property '"). Append(prop). Append("' not found").ToString()); } Object val = piSource.GetGetMethod().Invoke(dataItem, new Object[] { }); Type vct = a.ValueConverter; ConstructorInfo ci = vct.GetConstructor(new Type[] { }); IValueConverter vc = (IValueConverter)ci.Invoke(new Object[] { }); val = vc.ConvertForControl(val); piTarget.GetSetMethod().Invoke(c, new Object[] { val }); }
private static void CopyProperty(Object dataItem, ConnectionAttribute a, Control c) { PropertyInfo piSource = null; PropertyInfo piTarget = null; String prop = a.DataItemProperty; try { piSource = dataItem.GetType().GetProperty(prop); } catch (Exception ex) { throw new InitializerException( new StringBuilder("Source property '"). Append(prop). Append("' not found").ToString(), ex); } if (piSource == null) { throw new InitializerException( new StringBuilder("Source property '"). Append(prop). Append("' not found").ToString()); } prop = a.ControlProperty; try { piTarget = c.GetType().GetProperty(prop); } catch (Exception ex) { throw new InitializerException( new StringBuilder("Target property '"). Append(prop). Append("' not found").ToString(), ex); } if (piTarget == null) { throw new InitializerException( new StringBuilder("Target property '"). Append(prop). Append("' not found").ToString()); } Object val = piSource.GetGetMethod().Invoke(dataItem, new Object[] { }); Type vct = a.ValueConverter; ConstructorInfo ci = vct.GetConstructor(new Type[] { }); IValueConverter vc = (IValueConverter)ci.Invoke(new Object[] { }); val = vc.ConvertForControl(val); piTarget.GetSetMethod().Invoke(c, new Object[] { val }); }
public async Task <ConnectionAttribute> InsertAsync(string unparsedData, ConnectionAttribute connectionAttribute) { var insertedUnparesedData = await _context.UnparsedData.AddOneAsync(new UnparsedData() { ArrivalDateTime = DateTime.Now, Data = unparsedData }); return(await InsertAll(Parse(unparsedData), insertedUnparesedData.Id, connectionAttribute)); }
public void LoadScript(ScriptData scriptData) { ScriptData = scriptData; DeleteElements(graphElements.ToList()); //Debug.Log($"Loading script '{scriptData.name}' with {scriptData.Nodes.Count} nodes..."); // add nodes foreach (ScriptNodeData nodeData in scriptData.Nodes) { AddNode(nodeData); } // add edges foreach (ScriptNodeData nodeData in Nodes.Values) { Type nodeType = nodeData.GetType(); var connections = nodeType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => Attribute.IsDefined(x, typeof(ConnectionAttribute))); foreach (FieldInfo connection in connections) { ConnectionAttribute attr = connection.GetCustomAttribute <ConnectionAttribute>(); if (attr.ConnectionDirection != ConnectionAttribute.Direction.Output) { continue; } ScriptNodePortData outputPort = (ScriptNodePortData)connection.GetValue(nodeData); if (!outputPort.IsConnected) { //Debug.Log($"Node {nodeData.Id} connection {outputPort.Id} not connected"); continue; } AddEdge(nodeData.Id, outputPort.Id, outputPort.NodeId, outputPort.PortId); } var outputs = nodeType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => Attribute.IsDefined(x, typeof(OutputAttribute))); foreach (FieldInfo output in outputs) { OutputAttribute attr = output.GetCustomAttribute <OutputAttribute>(); ScriptNodePortData outputPort = (ScriptNodePortData)output.GetValue(nodeData); if (!outputPort.IsConnected) { //Debug.Log($"Node {nodeData.Id} output {outputPort.Id} not connected"); continue; } AddEdge(nodeData.Id, outputPort.Id, outputPort.NodeId, outputPort.PortId); } } }
private void AddConnectionImage(Type type) { // find the image corresponding with the connection so it can be displayed in the TreeView ConnectionAttribute attribute = (ConnectionAttribute)Attribute.GetCustomAttribute(type, typeof(ConnectionAttribute)); if (attribute?.IconResourceName != null && !connectionImageList.Images.ContainsKey(type.FullName)) { connectionImageList.Images.Add(type.FullName, attribute.GetIcon(type.Assembly)); } }
private static void CopyProperty <T>(T t, ConnectionAttribute a, Control c) where T : new() { PropertyInfo piSource = RetrieveSourceProperty(a, c); PropertyInfo piTarget = RetrieveTargetProperty <T>(t, a); Object val = piSource.GetGetMethod().Invoke(c, new Object[] { }); Type vct = a.ValueConverter; ConstructorInfo ci = vct.GetConstructor(new Type[] { }); IValueConverter vc = (IValueConverter)ci.Invoke(new Object[] { }); val = vc.ConvertForDataItem(val); piTarget.GetSetMethod().Invoke(t, new Object[] { val }); }
private void AddConnectionToolStripMenuItem_Click(object sender, EventArgs e) { try { ToolStripMenuItem menuItem = (ToolStripMenuItem)sender; Type connectionType = (Type)menuItem.Tag; IConnection connection = (IConnection)Activator.CreateInstance(connectionType, new object[] { ApplicationState.Default.ActiveProject }); ConnectionAttribute attribute = (ConnectionAttribute)Attribute.GetCustomAttribute(connectionType, typeof(ConnectionAttribute)); connection.Name = attribute.DisplayName; AddConnection(connection, ApplicationState.Default.ActiveProject.Connections.Count); } catch (Exception ex) { ApplicationState.Default.RaiseNotification(new NotificationEventArgs(NotificationType.Error, ex.Message, ex)); } }
private void ConnectionContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e) { try { BindableTreeNode connectionNode = ClientUtility.GetContextMenuTreeviewNode(dataSourceTreeView, sender); Type connectionType = connectionNode.DataSource.GetType(); ConnectionAttribute connectionAttribute = (ConnectionAttribute)Attribute.GetCustomAttribute(connectionType, typeof(ConnectionAttribute)); IConnection connection = (IConnection)connectionNode.DataSource; testConnectionToolStripMenuItem.Visible = connection is IAvailableProvider; openConnectionInBrowserToolStripMenuItem.Visible = connection is IUrlAddressable; openConnectionInBrowserToolStripMenuItem.Enabled = connection is IUrlAddressable && ((IUrlAddressable)connection).Url != default(Uri); testOpenToolStripSeparator.Visible = connection is IAvailableProvider || connection is IUrlAddressable; ConnectionCache cache = new ConnectionCache((IConnection)connectionNode.DataSource); clearCacheToolStripMenuItem.Enabled = cache.Count > 0; addDataSourceToolStripMenuItem.DropDownItems.Clear(); List <Type> dataSourceTypes = CoreUtility.GetInterfaceImplementorsWithAttribute(typeof(IDataSource), typeof(DataSourceAttribute)); foreach (Type dataSourceType in dataSourceTypes) { DataSourceAttribute dataSourceAttribute = (DataSourceAttribute)Attribute.GetCustomAttribute(dataSourceType, typeof(DataSourceAttribute)); if (connectionType == dataSourceAttribute.ConnectionType || connectionType.IsSubclassOf(dataSourceAttribute.ConnectionType)) { ToolStripMenuItem dataSourceToolStripMenuItem = new ToolStripMenuItem() { ImageScaling = ToolStripItemImageScaling.None, Tag = dataSourceType }; dataSourceToolStripMenuItem.Click += AddDataSourceToolStripMenuItem_Click; dataSourceToolStripMenuItem.Text = dataSourceAttribute.DisplayName; dataSourceToolStripMenuItem.ToolTipText = dataSourceAttribute.Description; dataSourceToolStripMenuItem.Image = dataSourceAttribute.GetIcon(dataSourceType.Assembly); addDataSourceToolStripMenuItem.DropDownItems.Add(dataSourceToolStripMenuItem); } } addDataSourceToolStripMenuItem.Enabled = addDataSourceToolStripMenuItem.DropDownItems.Count > 0; } catch (Exception ex) { ApplicationState.Default.RaiseNotification(new NotificationEventArgs(NotificationType.Error, ex.Message, ex)); } }
private async Task <ConnectionAttribute> InsertConnectionAttributes(string[] connectionAttributesData, string parentId) { if (connectionAttributesData.Length != 3) { return(null); } int qualityOfService = ParseInt(connectionAttributesData[2]); var connectionAttribute = new ConnectionAttribute( connectionAttributesData[1], qualityOfService, parentId ); await _context.ConnectionAttributes.AddOneAsync(connectionAttribute); return(connectionAttribute); }
private static void CopyDefaultValue <T>(T t, ConnectionAttribute a) where T : new() { Type dvpt = a.DefaultValueProvider; IDefaultValueProvider dvp = null; MethodInfo mi = dvpt.GetMethod("GetInstance", BindingFlags.Static | BindingFlags.Public); if (mi != null) { dvp = (IDefaultValueProvider)mi.Invoke(null, new Object[] { }); } else { ConstructorInfo ci = dvpt.GetConstructor(new Type[] { }); dvp = (IDefaultValueProvider)ci.Invoke(new Object[] { }); } Object val = dvp.GetDefaultValue(); PropertyInfo targetProperty = RetrieveTargetProperty <T>(t, a); targetProperty.GetSetMethod().Invoke(t, new Object[] { val }); }
private void DiscoverConnectionEdges( TypeAccessor sourceTypeAccessor, string sourceId, Type sourceType, object instance, List <ConnectionEdge> connectionEdges, InternalConnectionEdgeState internalConnectionEdgeState) { foreach (var member in sourceTypeAccessor.GetMembers()) { ConnectionAttribute connAttribute = member.GetAttribute(typeof(ConnectionAttribute), true) as ConnectionAttribute; if (connAttribute != null) { var value = sourceTypeAccessor[instance, member.Name]; if (value != null) { HandleConnectionEdge(sourceId, sourceType, connAttribute, member, value, connectionEdges, internalConnectionEdgeState); sourceTypeAccessor[instance, member.Name] = null; } } } }
protected override void InitializeView() { base.InitializeView(); Type nodeType = ScriptNodeData.GetType(); //Debug.Log($"Node 0x{Id:X} of type {nodeType}"); var connections = nodeType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => Attribute.IsDefined(x, typeof(ConnectionAttribute))); foreach (FieldInfo connection in connections) { ConnectionAttribute attr = connection.GetCustomAttribute <ConnectionAttribute>(); if (attr.ConnectionDirection != ConnectionAttribute.Direction.Input) { continue; } //Debug.Log($"Add input connection {attr.Name} to node 0x{Id:X}"); ScriptNodePortData inputPort = (ScriptNodePortData)connection.GetValue(ScriptNodeData); ScriptViewPort port = new ScriptViewPort(this, inputPort, Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(ScriptNodePortData)) { portName = attr.Name }; port.AddManipulator(new EdgeConnector <Edge>(EdgeConnectorListener)); Add(port); } var inputs = nodeType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => Attribute.IsDefined(x, typeof(InputAttribute))); foreach (FieldInfo input in inputs) { InputAttribute attr = input.GetCustomAttribute <InputAttribute>(); //Debug.Log($"Add input {attr.Name} of type {attr.Type} to node 0x{Id:X}"); ScriptNodePortData inputPort = (ScriptNodePortData)input.GetValue(ScriptNodeData); ScriptViewPort port = new ScriptViewPort(this, inputPort, Orientation.Horizontal, Direction.Input, Port.Capacity.Single, attr.Type) { portName = attr.Name }; port.AddManipulator(new EdgeConnector <Edge>(EdgeConnectorListener)); Add(port); } foreach (FieldInfo connection in connections) { ConnectionAttribute attr = connection.GetCustomAttribute <ConnectionAttribute>(); if (attr.ConnectionDirection != ConnectionAttribute.Direction.Output) { continue; } //Debug.Log($"Add output connection {attr.Name} to node 0x{Id:X}"); ScriptNodePortData outputPort = (ScriptNodePortData)connection.GetValue(ScriptNodeData); ScriptViewPort port = new ScriptViewPort(this, outputPort, Orientation.Horizontal, Direction.Output, Port.Capacity.Single, typeof(ScriptNodePortData)) { portName = attr.Name }; port.AddManipulator(new EdgeConnector <Edge>(EdgeConnectorListener)); Add(port); } var outputs = nodeType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => Attribute.IsDefined(x, typeof(OutputAttribute))); foreach (FieldInfo output in outputs) { OutputAttribute attr = output.GetCustomAttribute <OutputAttribute>(); //Debug.Log($"Add output {attr.Name} of type {attr.Type} to node 0x{Id:X}"); ScriptNodePortData outputPort = (ScriptNodePortData)output.GetValue(ScriptNodeData); ScriptViewPort port = new ScriptViewPort(this, outputPort, Orientation.Horizontal, Direction.Output, Port.Capacity.Single, attr.Type) { portName = attr.Name }; port.AddManipulator(new EdgeConnector <Edge>(EdgeConnectorListener)); Add(port); } }
/// <summary> /// Renders the Connection Definition settings as user editable controls /// </summary> /// <param name="def">Definition</param> private void Render(IConnectionDefinition def) { this.lblDescrip.Text = def.StoreDescription; int i = 0; tblSettings.Controls.Clear(); foreach (KeyValuePair <PropertyInfo, ConnectionAttribute> setting in def.OrderBy(s => s.Value.DisplayOrder)) { if (setting.Value.Type != ConnectionSettingType.Boolean) { Label label = new Label(); label.Text = setting.Value.DisplayName + Resources.Colon; label.TextAlign = ContentAlignment.MiddleLeft; tblSettings.Controls.Add(label, 0, i); } switch (setting.Value.Type) { case ConnectionSettingType.String: case ConnectionSettingType.Password: //String/Password so show a Textbox TextBox box = new TextBox(); String s = (String)setting.Key.GetValue(def, null); box.Text = s ?? String.Empty; box.Width = 225; box.Tag = setting.Key; if (setting.Value.Type == ConnectionSettingType.Password) { box.PasswordChar = '*'; } //Add the Event Handler which updates the Definition as the user types box.TextChanged += (_, args) => { var propertyInfo = box.Tag as PropertyInfo; if (propertyInfo != null) { propertyInfo.SetValue(def, box.Text, null); } }; //Show DisplaySuffix if relevant if (!String.IsNullOrEmpty(setting.Value.DisplaySuffix)) { FlowLayoutPanel flow = new FlowLayoutPanel(); flow.Margin = new Padding(0); flow.Controls.Add(box); Label suffix = new Label(); suffix.Text = setting.Value.DisplaySuffix; suffix.AutoSize = true; suffix.TextAlign = ContentAlignment.MiddleLeft; flow.Controls.Add(suffix); flow.WrapContents = false; flow.AutoSize = true; flow.AutoScroll = false; tblSettings.Controls.Add(flow, 1, i); } else { tblSettings.Controls.Add(box, 1, i); } break; case ConnectionSettingType.Boolean: //Boolean so show a Checkbox CheckBox check = new CheckBox(); check.AutoSize = true; check.TextAlign = ContentAlignment.MiddleLeft; check.CheckAlign = ContentAlignment.MiddleLeft; check.Checked = (bool)setting.Key.GetValue(def, null); check.Text = setting.Value.DisplayName; check.Tag = setting.Key; //Add the Event Handler which updates the Definition when the Checkbox changes check.CheckedChanged += (_, args) => { var propertyInfo = check.Tag as PropertyInfo; if (propertyInfo != null) { propertyInfo.SetValue(def, check.Checked, null); } }; this.tblSettings.SetColumnSpan(check, 2); this.tblSettings.Controls.Add(check, 0, i); break; case ConnectionSettingType.Integer: //Integer so show a Numeric Up/Down control NumericUpDown num = new NumericUpDown(); num.ThousandsSeparator = true; num.DecimalPlaces = 0; int val = (int)setting.Key.GetValue(def, null); if (setting.Value.IsValueRestricted) { num.Minimum = setting.Value.MinValue; num.Maximum = setting.Value.MaxValue; } else { num.Minimum = Int32.MinValue; num.Maximum = Int32.MaxValue; } num.Value = val; num.Tag = setting.Key; //Add the Event Handler which updates the Definition as the number changes num.ValueChanged += (_, args) => { var propertyInfo = num.Tag as PropertyInfo; if (propertyInfo != null) { propertyInfo.SetValue(def, (int)num.Value, null); } }; tblSettings.Controls.Add(num, 1, i); break; case ConnectionSettingType.Enum: //Enum so show a ComboBox in DropDownList Mode ComboBox ebox = new ComboBox(); ebox.DropDownStyle = ComboBoxStyle.DropDownList; ebox.DataSource = Enum.GetValues(setting.Key.PropertyType); ebox.SelectedItem = setting.Key.GetValue(def, null); ebox.Tag = setting.Key; //Add the Event Handler which updates the Definition as the selection changes ebox.SelectedIndexChanged += (_, args) => { var propertyInfo = ebox.Tag as PropertyInfo; if (propertyInfo != null) { propertyInfo.SetValue(def, ebox.SelectedItem, null); } }; tblSettings.Controls.Add(ebox, 1, i); break; case ConnectionSettingType.File: //File so show a TextBox and a Browse Button String file = (String)setting.Key.GetValue(def, null); FlowLayoutPanel fileFlow = new FlowLayoutPanel(); fileFlow.Margin = new Padding(0); fileFlow.WrapContents = false; fileFlow.AutoSize = true; fileFlow.AutoScroll = false; TextBox fileBox = new TextBox(); fileBox.Width = 225; fileBox.Text = file ?? String.Empty; fileBox.Width = 225; fileBox.Tag = setting.Key; fileFlow.Controls.Add(fileBox); Button browse = new Button(); browse.Text = Resources.Browse; browse.Tag = setting.Value; fileFlow.Controls.Add(browse); //Add the Event Handler which updates the Definition as the user types fileBox.TextChanged += (_, args) => { var propertyInfo = fileBox.Tag as PropertyInfo; if (propertyInfo != null) { propertyInfo.SetValue(def, fileBox.Text, null); } }; //Add the Event Handler for the Browse Button browse.Click += (_, args) => { ConnectionAttribute attr = browse.Tag as ConnectionAttribute; if (attr == null) { return; } this.ofdBrowse.Title = string.Format(Resources.BrowseFor, attr.DisplayName); this.ofdBrowse.Filter = (String.IsNullOrEmpty(attr.FileFilter) ? "All Files|*.*" : attr.FileFilter); if (this.ofdBrowse.ShowDialog() == DialogResult.OK) { fileBox.Text = this.ofdBrowse.FileName; } }; tblSettings.Controls.Add(fileFlow, 1, i); break; } i++; } }
private async Task <ConnectionAttribute> InsertAll(List <string[]> parsed, string parentId, ConnectionAttribute connectionAttribute) { try { for (int i = 0; i < parsed.Count; i++) { switch (Int32.Parse(parsed[i][0])) { case 0: await InsertReset(parsed[i], parentId, connectionAttribute.DeviceId); break; case 1: connectionAttribute = await InsertConnectionAttributes(parsed[i], parentId); break; case 2: await InsertGps(parsed[i], parentId, connectionAttribute.DeviceId); break; case 3: await InsertHardwareStatus(parsed[i], parentId, connectionAttribute.DeviceId); break; } } return(connectionAttribute); } catch (Exception) { return(connectionAttribute); } }
private void HandleConnectionEdge( string sourceId, Type sourceType, ConnectionAttribute connAttribute, Member member, object edgeObjectInstance, List <ConnectionEdge> connectionEdges, InternalConnectionEdgeState internalConnectionEdgeState) { var edgeType = member.Type; var edgeTypeAccessor = TypeAccessor.Create(edgeType); var connectionEdge = new ConnectionEdge { SourceType = sourceType.AssemblyQualifiedName, SourceFieldName = member.Name, SourceId = sourceId, MetaType = edgeType.AssemblyQualifiedName }; Member destinationId = null; Member destinationModel = null; foreach (var edgeMember in edgeTypeAccessor.GetMembers()) { var connectionEdgeDestinationKey = edgeMember.GetAttribute(typeof(ConnectionEdgeDestinationKeyAttribute), false) as ConnectionEdgeDestinationKeyAttribute; if (connectionEdgeDestinationKey != null) { destinationId = edgeMember; } else { var connectionEdgeDestination = edgeMember.GetAttribute(typeof(ConnectionEdgeDestinationAttribute), false) as ConnectionEdgeDestinationAttribute; if (connectionEdgeDestination != null) { destinationModel = edgeMember; } } } if (destinationId == null) { throw new InvalidProgramException("Property with ConnectionEdgeDestinationKeyAttribute is required on a Connection."); } if (destinationModel == null) { throw new InvalidProgramException("Property with ConnectionEdgeDestinationAttribute is required on a Connection."); } var destId = edgeTypeAccessor[edgeObjectInstance, destinationId.Name]; if (destId == null) { throw new InvalidProgramException("Value on property with ConnectionEdgeDestinationKeyAttribute is required!"); } // Eval destination model instance first. var destObject = edgeTypeAccessor[edgeObjectInstance, destinationModel.Name]; if (destObject != null) { var id = destId.ToString(); DiscoverConnectionEdges(edgeTypeAccessor, id, edgeType, destObject, connectionEdges, internalConnectionEdgeState); internalConnectionEdgeState.InvokeAction(destObject, id, destinationModel.Type.Name); edgeTypeAccessor[edgeObjectInstance, destinationModel.Name] = null; } connectionEdge.DestinationId = destId.ToString(); connectionEdge.DestinationFieldName = destinationId.Name; connectionEdge.Id = $"{connectionEdge.SourceFieldName}_{connectionEdge.SourceId}"; connectionEdge.MetaFieldName = destinationModel.Name; connectionEdge.MetaValue = JsonConvert.SerializeObject(edgeObjectInstance); connectionEdges.Add(connectionEdge); }