How do I add buttons to a canvas via editor code?

I have a “BulletinBoard” canvas prefab that represents an empty shell that I intend to instantiate in various places and seed with different messages.

I use an editor script to spawn this prefab into my scene and to add buttons for each message to toggle them visible. To do that I pass the instantiated game object into a utility class.

The code below isn’t exactly my code, which would be too convoluted to post, but it is the same in concept.

Editor code:

var bulletinBoard = PrefabUtility.InstantiatePrefab(bulletinBoardPrefab) as GameObject;
var bulletingBoardUtility = new BulletinBoardUtility(bulletinBoard);
bulletingBoardUtility.SeedMessages(messages);

Utility class:

public class BulletinBoardUtility
{
    BulletinBoardController controller; // Exists in the prefab

    public BulletinBoardUtility(GameObject gameObject)
    {
        controller = gameObject.GetComponent<BulletinBoardController>();
    }

    void SeedMessages(Message[] messages)
    {
        foreach (var message in messages)
        {
            // Code that adds an image child to the canvas for the message

            imageChild.AddComponent<Button>()
                .onClick.AddListener(() => controller.Toggle(message.Id));
        }
    }
}

Unfortunately this doesn’t seem to work. The “On Click ()” list for the message buttons is just empty and unsurprisingly nothing happens when I click them. They do work fine if I manually add listeners after my editor script ran.

My questions are a) should this work in principle (i.e. do I have a bug somewhere in my code) or b) am I missing an obvious reason why this wouldn’t work and how can I fix it?

I got it working using UnityEventTools.

UnityEventTools.AddIntPersistentListener(
    imageChild.AddComponent<Button>().onClick,
    new UnityAction<int>(controller.Toggle),
    message.Id
);