Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A type safe node based workflow library for .NET8

License

NotificationsYou must be signed in to change notification settings

HerveZu/SafeNodes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

This package lets you easily create asynchronous & type safe node workflows (called blueprints).It consists in 3 main projects :

  • SafeNodes.Design : The contracts necessary to define your nodes system, such as nodes, events, types, etc...

  • SafeNodes.Runtime : The runtime that executes blueprints and generates schemes representing your nodes system definition.

  • SafeNodes.Internal : A set of tools used internally.

Note

By design, user facing contracts such as events, values or nodes must implement marker interfaces.This enforces contracts to be explicitly define and decoupled from logic.

Getting started

A blueprint is made of at least one event and one node.Each blueprint requires exactly one event which is the entrypoint.The entrypoint nodes are the nodes triggered by the events which eventually trigger other nodes.You may want data to flow between your event and nodes. To shape this data, custom values can be defined.Events, nodes, values and their properties can be referenced in the blueprint definition.Use theApi attribute to explicitly create explicit compile-time references.

Using SafeNodes assemblies

// when defining contractsusingSafeNodes.Design;// when using the runtimeusingSafeNodes.Runtime;

Defining a custom value

[Api("my-text-value")]publicsealedrecordTextValue(stringValue):IValue;

Values can define initializers, they create a new instance of the value from a raw string value.This initializer takes raw values such as trim this and returns a trimmedTextValue (trim this).

[Api("my-trim-text-initializer")]publicsealedclassTrimTextInitializer:IValueInitializer<TextValue>{publicTextValueInitializeValue(stringrawValue){returnnewTextValue(rawValue.Trim());}}

Defining an event

// you could have as much data as you want here, I just keep things simplepublicsealedrecordBlankData:IEventData;[Api("my-blank-event")]publicsealedclassBlankEvent:IEvent<BlankData>{publicvoidDefine(BlankDatadata){// initializes the event using the data if needed}// Whether this event will be triggerd, you can use the event data here.publicboolIsActivated()=>true;}

Defining a node

[Api("my-print-node")]publicsealedclassPrintNode(IInput<TextValue>textToPrint,ITriggerdone,IOutput<TextValue>textOutput):INode{[Api("print-text")]publicIInput<TextValue>TextToPrint{get;}=textToPrint;[Api("text")]publicIOutput<TextValue>TextOutput{get;}=textOutput;[Api("done")]publicITriggerDone{get;}=done;// this is where the logic goespublicasyncTask<ErrorOr<Success>>Execute(CancellationTokencancellationToken){vartextToPrint=TextToPrint.Get();Console.WriteLine(textToPrint);TextOutput.Set(textToPrint);// awaits for the children nodes (and their children) to completeawaitDone.Trigger(cancellationToken);returnResult.Success;}}

Pipelines

Pipelines let you define logic around execution of nodes. You can either target all nodes or specific ones using interfaces.In this example, the pipeline only targets the nodes implementingIBenchmarkMe.

// make nodes to benchmark implement this interfacepublicinterfaceIBenchmarkMe;publicsealedclassBenchmarkNodes<TNode>:INodeContextPipeline<TNode>whereTNode:IBenchmarkMe,INode{publicasyncTask<IErrorOr>Next(TNodenode,NodeContextPipelineNextnext,CancellationTokencancellationToken){varstopwatch=newStopwatch();varresult=awaitnext();Console.WriteLine($"{typeof(TNode)} execution time ticks :{stopwatch.ElapsedTicks}");returnresult;}}

Running a blueprint

// setup a DI containervarbuilder=newContainerBuilder();// don't forget to add the SafeNodesModule in the DI containerbuilder.RegisterModule<SafeNodesModule>();// your defined types need to be added to the DI container !!// the recommended lifetime is Transient (InstancePerDependency)builder.RegisterTypes([typeof(BlankEvent),typeof(PrintNode),typeof(TrimTextInitializer)]).AsImplementedInterfaces().InstancePerDependency();builder.RegisterGeneric(typeof(BenchmarkNodes<>)).AsImplementedInterfaces().InstancePerDependency();varapp=builder.Build();awaitusingvarscope=app.BeginLifetimeScope();varblueprintRuntime=scope.Resolve<IBlueprintRuntime>();Console.WriteLine("Runtime ...");// this is your blueprint definition.// use the API references here.varblueprint=newBlueprint{Event=newBlueprintEvent{EventReference="my-blank-event"},Nodes=[newBlueprintNode{// this id is a runtime id,// this allows to have multiple nodes of the same typesId="node-1",NodeReference="my-print-node",IsEntrypoint=true,// this node is triggered by the eventInputs=[newBlueprintNodeInput{InputReference="print-text",// set the input value from a raw value and an initializerInitializer=newBlueprintNodeInputInitializer{InitializerReference="my-trim-text-initializer",RawValue=" Hello, World ! "}}],},newBlueprintNode{Id="node-2",NodeReference="my-print-node",Inputs=[newBlueprintNodeInput{InputReference="print-text",// this is the value to set to input to,// it comes from the output 'text' of the node 'node-id'Source=newBlueprintNodeInputSource{NodeId="node-1",OutputReference="text"}}],// this node is not triggered by the event,// rather by the 'done' trigger of the 'node-1' nodeTrigger=newBlueprintNodeTrigger{NodeId="node-1",TriggerReference="done"}}]};// execute the blueprint, throws if the event data is not compatible with the blueprint's eventawaitblueprintRuntime.ExecuteMandatory(blueprint,newBlankData());// execute the blueprint or skip when the event data is not compatible// var blueprintWasExecuted = await blueprintRuntime.Execute(blueprint, new BlankData());

About

A type safe node based workflow library for .NET8

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp