portdic 1.1.93

dotnet add package portdic --version 1.1.93
                    
NuGet\Install-Package portdic -Version 1.1.93
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="portdic" Version="1.1.93" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="portdic" Version="1.1.93" />
                    
Directory.Packages.props
<PackageReference Include="portdic" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add portdic --version 1.1.93
                    
#r "nuget: portdic, 1.1.93"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package portdic@1.1.93
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=portdic&version=1.1.93
                    
Install as a Cake Addin
#tool nuget:?package=portdic&version=1.1.93
                    
Install as a Cake Tool

PortDic

PortDic is a .NET library for industrial equipment automation built on the MCF pattern (Model · Controller · Flow). All behavior is declared through attributes — no manual wiring required.


Entry Definition Attributes

These attributes define what data entries exist in the Port database.

[Page(string category)]

Marks a class as an entry container. When passed to Port.Push(reponame, obj), Port scans the class for [Entry] and [EntryEnum] fields and registers them all.

[Page("EFEM")]
public partial class CustomEFEM
{
    [EntryEnum("Unknown", "Off", "On")]
    public const string UnkOffOn = "UnkOffOn";

    [Entry(PortDataType.Char)]
    public const string LP1_Cont1_o = "EFEM.LP1_Cont1_o";

    [Entry(PortDataType.Enum, EnumName = UnkOffOn)]
    public const string LP1_OffOn_o = "EFEM.LP1_OffOn_o";
}
Port.Push("sample", new CustomEFEM());

[Entry(PortDataType, EnumName = null)]

Marks a const string field as an entry definition. The field value ("EFEM.LP1_OffOn_o") is the entry key stored in the database.

Parameter Description
PortDataType Data type: Char, F4, F8, I4, U4, Enum, …
EnumName Enum key to bind — must match the value of the corresponding [EntryEnum] field

[EntryEnum(params string[] elements)]

Declares an enum type on a const string field. Elements are zero-indexed (index = stored integer value). The field value (not the field name) becomes the enum key.

// Key = "UnkTurnOffOn", values: 0→Unknown, 1→TurnOff, 2→TrunOn
[EntryEnum("Unknown", "TurnOff", "TrunOn")]
public const string UnkTurnOffOn = "UnkTurnOffOn";

[EntryEnum] fields are always pushed before [Entry] fields so enum references always resolve.


Model Attributes

Models bind C# properties to Port database entries. Each property represents one signal; multiple [Binding] attributes map it to different controller instances.

[Model]

Marks a class as a data model. Model instances are injected automatically into [FlowStep] method parameters.

[Model]
public class LoadportModel
{
    [Binding("LP1", CustomEFEM.LP1_Cont1_o)]
    [Binding("LP2", EFEM.LP2_Cont_o)]
    public Entry LP_Cont_o { get; set; }

    [Binding("LP1", CustomEFEM.LP1_OffOn_o)]
    public Entry LP_OffOn_o { get; set; }
}

[Binding(string controllerName, string entryKey)]

Binds a model property to a Port entry key for a specific controller instance name. Multiple [Binding] attributes on one property map the same logical signal across instances.

// "LP1" instance reads/writes "EFEM.LP1_OffOn_o"
// "LP2" instance reads/writes "EFEM.LP2_OffOn_o"
[Binding("LP1", EFEM.LP1_OffOn_o)]
[Binding("LP2", EFEM.LP2_OffOn_o)]
public Entry OffOn { get; set; }

Controller & Flow Attributes

Controllers define the logic that operates on models. Each controller contains one or more named flows composed of sequential steps.

[Controller]

Marks a class as a flow controller. Register it with Port.Add<TController, TModel>(instanceName).

[Controller]
public class LoadportController { ... }
Port.Add<LoadportController, LoadportModel>("LP1");
Port.Add<LoadportController, LoadportModel>("LP2");

Each registered instance gets its own model and flow state, isolated from other instances.

[Flow(string flowName)]

Marks a nested class inside a [Controller] as a named workflow. A flow is a sequence of steps executed in order.

[Controller]
public class LoadportController
{
    [Flow("Load")]
    public class Load
    {
        [FlowHandler]
        public IFlowHandler Handler { get; set; } = null!;

        [FlowStep(0)]
        public void CheckReady(LoadportModel model) { ... }

        [FlowStep(1)]
        public void Execute(LoadportModel model) { ... }
    }
}

Start or stop a flow:

Port.Set("LP1", FlowAction.Executing);   // start "Load" flow on LP1
Port.Set("LP1", FlowAction.Canceled);    // cancel

[FlowStep(int index)]

Marks a method as a workflow step. Steps execute in index order. The method receives a model instance automatically.

[FlowStep(0)]
public void CheckReady(LoadportModel model)
{
    if (model.LP_Main_Air_i.String() == "On")
        Handler?.Next();       // advance to step 1
}

Overloads:

Signature Description
[FlowStep(int index)] Basic ordered step
[FlowStep(int index, params string[] relatedEntry)] Step with related entry names
[FlowStep(int index, ushort ceid, ...)] Step that fires a SECS collection event

[FlowHandler]

Injects the IFlowHandler into the flow class. Required for calling Next() or Jump().

[FlowHandler]
public IFlowHandler Handler { get; set; } = null!;
Method Description
Handler.Next() Execute the next step in sequence
Handler.Jump(int index) Skip to a specific step index

[FlowWatcherCompare(string key, string op, object value)]

Gate attribute on a [FlowStep] method. The step is only entered when the condition is met.

[FlowStep(1)]
[FlowWatcherCompare(EFEM.LP1_Main_Air_i, "==", "On")]
public void Execute(LoadportModel model) { ... }

Multiple [FlowWatcherCompare] on the same method are combined with AND by default. Set OR = true for logical OR:

[FlowWatcherCompare(EFEM.LP1_Main_Air_i, "==", "On")]
[FlowWatcherCompare(EFEM.LP1_OffOn_o, "!=", "Unknown", OR = true)]
public void Execute(LoadportModel model) { ... }

Supported operators: ==, !=, >=, <=, >, <

[FlowWatcherAction(string entryKey, object value)]

Side-effect attribute on a [FlowStep] method. Automatically sets a Port entry when the step executes.

[FlowStep(1)]
[FlowWatcherAction(EFEM.LP1_OffOn_o, "On")]
public void TurnOn(LoadportModel model)
{
    Handler?.Next();
}

[Timeout(int ms, string controllerName, int alarmId)]

Sets a timeout on a [FlowStep]. If the step does not call Handler.Next() within ms milliseconds, an alarm is triggered.

[FlowStep(2)]
[Timeout(5000, "LP1", 101)]
public void WaitComplete(LoadportModel model) { ... }

Handler Injection Attributes

These attributes inject runtime services into flow classes and package classes.

[FlowHandler]IFlowHandler

Step navigation inside a flow. See Controller & Flow Attributes.

[Logger]ILogger

Injects a logger into any package or controller class.

[Logger]
public ILogger Logger { get; set; }
Logger.Write("step started");

[Import(string packageName, string instanceKey)]IReference

Imports a function or reference from another registered package.

[Import("Heater", "Heater1")]
public IReference HeaterRef { get; set; }

Package Attributes

Used in the older [Package] model (non-MCF). Still supported for backward compatibility.

[Package]

Marks a class as a managed package. Port instantiates and manages its lifecycle.

[API]

Exposes a property or method as a REST/gRPC endpoint callable from external clients.

[API]
public string Power
{
    set { /* handle */ }
    get { return _power; }
}

[Valid(string message)]

Marks a method as a validation guard. Called before the package is used; returns false to block.

[Valid("device not connected")]
public bool Valid() => _connected;

[Shared]

Marks a method as a handler for shared inter-package data updates.

[Shared("S1F1")]
public void OnS1F1Received(IShared message) { ... }

Event Handlers

Subscribe to these static events on the Port class after calling Port.Run().

Event Args Description
Port.OnReady EventArgs Fired once when the system reaches Synchronized state
Port.OnStatusChanged PortStatusArgs Port lifecycle transitions
Port.OnOccurred PortEventArgs Info / Warning / Error / Reject events
Port.OnRequest PortRequestArgs Incoming external requests
Port.OnFlowOccured FlowOccuredArgs Flow started
Port.OnFlowFinished FlowFinishedArgs Flow completed
Port.OnFlowIssue FlowIssueArgs Flow stopped, canceled, or errored
Port.OnReady += (s, e) =>
{
    var keys = Port.GetEntryKeysWithCategory("EFEM");
};

Port.OnFlowFinished += (s, e) =>
{
    Console.WriteLine($"{e.ControllerName}.{e.FlowName} finished");
};
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on portdic:

Package Downloads
Port.SDK

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.93 0 4/12/2026
1.1.92 41 4/9/2026
1.1.91 43 4/8/2026
1.1.90 92 4/6/2026
1.1.89 83 4/5/2026
1.1.88 89 4/1/2026
1.1.87 86 3/31/2026
1.1.86 88 3/29/2026
1.1.85 88 3/24/2026
1.1.84 85 3/23/2026
1.1.83 85 3/18/2026
1.1.82 86 3/17/2026
1.1.81 89 3/15/2026
1.1.80 96 3/10/2026
1.1.79 83 3/9/2026
1.1.78 88 3/2/2026
1.1.77 469 12/9/2025
1.1.76 459 12/8/2025
1.1.75 309 11/12/2025
1.1.74 309 11/11/2025
Loading failed