Skip to content

3. Creating Machines

Ovan Crone edited this page Apr 11, 2018 · 9 revisions

We have explored Schematics and StateEngines; now we will create instances of Machines to run our Schematic.

We will continue to re-use the Schematic defined in Creating a Schematic.

var schematic = REstateHost.Agent
    .CreateSchematic<string, string>("LoggerMachine")
    .WithState("Created", state => state
        .AsInitialState())
    .WithState("Ready", state => state
        .WithTransitionFrom("Created", "log")
        .WithReentrance("log")
        .WithAction("log info", onEntry => onEntry
            .DescribedAs("Logs the transition as a message.")
            .WithSetting(
                key: "messageFormat", 
                value: "{schematicName}({machineId}) entered {state} on {input}. " +
                       "Message: {payload}")))
    .Build();

We also will follow the same process as Creating a StateEngine.

var stateEngine = REstateHost.Agent
    .GetStateEngine<string, string>();

Creating a Machine

var machine = await stateEngine.CreateMachineAsync(schematic);

CreateMachineAsync will return an IStateMachine<string, string>. Notice how the state and input types match the StateEngine and Schematic.

IStateMachine<TState, TInput> has only one property: MachineId, which is a string that uniquely identifies the Machine. MachineId is intentionally opaque, which means the value shouldn't be relied upon for anything other than equality. While most implementations will use a GUID, that may change in the future for many reasons.

Creating a Machine from a Stored Schematic

In a previous step we looked at storing Schematics for future use. One of the uses of a stored Schematic is creating a Machine without a reference to the Schematic. This is done by using the Schematic's name instead:

var storedSchematicMachine = await stateEngine.CreateMachineAsync("LoggerMachine");

Machine Schematic

You can also retrieve the Schematic for any Machine for which you have a reference.

var machineSchematic = await machine.GetSchematicAsync();

Machine Metadata

Machines can also be given a set of metadata that can be referenced in connectors for business logic. To add metadata when creating a machine, just include it as the second parameter in the create call.

var metadata = new Dictionary<string, string>
{
    ["SomeKey"] = "SomeValue"
};

var machineWithMetadata = await stateEngine.CreateMachineAsync(schematic, metadata);

You can then retrieve metadata later:

var retrievedMetadata = await machineWithMetadata.GetMetadataAsync();

Metadata is returned as an IReadOnlyDictionary<string, string> as it is not meant to be mutated once stored on a Machine.

What's Next?

We will next interact with the Machine we just created to Change State with Input.