Derive from CustomNodeManager2 (I named it DataAccessNodeManager) and add the following method to it:
private NodeId AddDataType<T>() where T : struct, Enum
{
var enumFields = Enum
.GetNames<T>()
.Zip(Enum.GetValues<T>())
.Select(item =>
{
return new EnumField
{
Name = item.First,
Value = Convert.ToInt32(item.Second)
};
})
.ToArray();
var enumDefinition = new EnumDefinition { Fields = enumFields };
var nodeId = new NodeId(++_nodeId, NamespaceIndex);
var enumType = new DataTypeState()
{
NodeId = nodeId,
BrowseName = typeof(T).Name,
DisplayName = typeof(T).Name,
SuperTypeId = DataTypeIds.Enumeration,
DataTypeDefinition = new ExtensionObject(enumDefinition)
};
AddPredefinedNode(SystemContext, enumType);
return nodeId;
}
Then, in your derived class, use it as follows:
class DataAccessNodeManager : CustomNodeManager2
{
public DataAccessNodeManager(IServerInternal server)
: base(server, ...)
{
//
}
public override void CreateAddressSpace(IDictionary<NodeId, IList<IReference>> externalReferences)
{
lock (Lock)
{
var myNodeId = AddDataType<HlbCompressor>();
// ... add other nodes and use myNodeId for the `DataType` property
}
}
}
The often used UaExpert client software then shows the enum name next to its value: