C# Custom Node - How to Output Custom Classes?

Hi All,

I have a custom data structure - e.g. Person class as seen below and want to send an instance of this as my nodes output.

I initialise a new class and assign all values, then try to create an associative node via AstFactory.BuildPrimitiveNodeFromObject since this seems to be the only way to support custom data and afterwards I want to assign this to the output 0 using AstFactory.BuildAssignment.

However, this does not work and the plugin crashes with the following message:
ProtoCore.Exceptions.CompilerInternalException: ‘Exception of type ‘ProtoCore.Exceptions.CompilerInternalException’ was thrown.’

Any idea what went wrong or how to do this in a better way (preferably not using the detour of a zero touch function)?

Code:

using System;
using System.Collections.Generic;
using Dynamo.Graph.Nodes;
using ProtoCore.AST.AssociativeAST;

namespace Plugin
{

public class Person
{
    public int ID { get; set; }
    public string Prename { get; set; }
    public string Surname { get; set; }
    public Person() { }
}

[IsDesignScriptCompatible]
[NodeName("Plugin")]
[NodeDescription("Plugin")]
[NodeCategory("Plugin")]
[OutPortNames("P")]
[OutPortTypes("")]
[OutPortDescriptions("Person")]
public class Person_Node : NodeModel
{
    public Person_Node()
    {
        RegisterAllPorts();
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
    {
        Person p = new Person() { ID = 1, Prename = "Frank", Surname = "Gehry" };
        var assnode = AstFactory.BuildPrimitiveNodeFromObject((object)p);
        return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), assnode) };
    }

}

}

Is there any particular reason to not use Zero touch nodes?

Yes, these nodes have a custom UI and this data structure (Person is just an example, other ones have a lot more parameters) is created using input from UI elements (textbox etc.) and the data structure is already created in the same class to be displayed properly in another UI element (list etc.)

So it makes sense to use this readily created class as output directly and not split it back into all it’s basic parts (int, string), deliver those to a zero touch function and get back the same class just in a format that Dynamo understands. This wouldn’t be very efficient.

Fair enough! I would try using AstFactory.BuildFunctionCall instead. There are several examples on the Dynamo Revit repo implementing this. I also did something similar to return a custom enum value on this example.

build primitive is for building primitives like ints and strings, also you cannot import this assembly via zero touch you should make a package which contains this dll.