SapphireDb logo SapphireDb

Actions

SapphireDb comes with an alternative for controllers. They are called ActionHandler. You can use them like controllers in Asp.Net. You can define public methods that are exposed through the sapphire interfaces.

Basic example

Just create a class in your project and derive it from ActionHandlerBase.
You can use dependency injection in the constructor of the class.
The methods allow any serializable return type and you can also use async methods.
Calling the methods on client side is pretty easy. Just pass the name of the handler as first parameter and the name of the method as second.
Every other parameters will be used as parameters for the method.
\f:(typescript:Angular) this.db.execute('example.MethodWithParameters', 'parameter1', 'parameter2')\n \t.subscribe(console.log); \f:(csharp:ExampleActions.cs:Server) public class ExampleActions : ActionHandlerBase\n {\n \tprivate readonly ExampleDb db;\n\n \tpublic ExampleActions(ExampleDb db)\n \t{\n \tthis.db = db;\n \t}\n\n \tpublic string MethodWithParameters(string param1, string param2)\n \t{\n \t\treturn param1 + param2;\n \t}\n }

Stream data from server

You can also stream async data from server to client.
\f:(typescript:Angular) this.db.execute('example.AsyncEnumerableTest').subscribe(\n \tActionHelper.result(\n \t\t() => console.log('complete'),\n \t\t(value) => console.log(value),\n \t\t(notification) => console.warn(notification)\n \t));\n );\n\n // The code of the above example\n const result$ = this.db.execute<number, string>('example.AsyncEnumerableTest').pipe(\n \tshareReplay()\n );\n\n this.rangeValueStream$ = result$.pipe(\n \tfilter(v => v.type === ExecuteResponseType.Async),\n \tmap(v => v.result)\n );\n\n this.rangeValueStatus$ = result$.pipe(\n \tfilter(v => v.type === ExecuteResponseType.Notify),\n \tmap(v => v.notification)\n ); \f:(csharp:AsyncActions.cs:Server) public class AsyncActions : ActionHandlerBase\n {\n \tpublic async IAsyncEnumerable<string> AsyncEnumerableTest()\n \t{\n \t\tfor (int i = 0; i <= 100; i++)\n \t\t{\n \t\t\tyield return i.ToString();\n\n \t\t\tif (i % 10 == 0)\n \t\t\t{\n \t\t\t\tNotify("Progress: " + i + "%");\n \t\t\t}\n\n \t\t\tawait Task.Delay(10);\n \t\t}\n \t}\n }

Stream data to server (and back to client)

Streaming data from client to server is also possible. It is also possible to do both.
\f:(typescript:Angular) const subject$ = new ReplaySubject<string>();\n this.streamValueResponse$ = this.db.execute<string>('example.StreamTest', subject$);\n subject$.next('value');\n subject$.complete(); \f:(csharp:AsyncActions.cs:Server) public class AsyncActions : ActionHandlerBase\n {\n \tpublic async IAsyncEnumerable<string> StreamTest(IAsyncEnumerable<string> inputStream)\n \t{\n \t\tawait foreach (string input in inputStream)\n \t\t{\n \t\t\tyield return input + " from server";\n \t\t}\n \t}\n }

Notifications

Because SapphireDb allows a bidirectional communication between client and server you can also send additional notifications during method execution. This is useful to transfer a state for example.
Use the Notify-method in your action handler to achieve that.
The client side can use the action helper to distinguish between notification and final result.
\f:(typescript:Angular) this.db.execute('example.MethodWithParameters', 'parameter1', 'parameter2')\n \t.subscribe(ActionHelper.result<string, number>(\n \t\t(result) => {\n \t\t\talert(result);\n \t\t},\n \t\t(notification) => {\n \t\t\tconsole.log(notification);\n \t\t}\n \t)\n ); \f:(csharp:AsyncActions.cs:Server) public class AsyncActions : ActionHandlerBase\n {\n \tpublic async Task<string> AsyncDelay()\n \t{\n \t\tfor (int i = 0; i <= 100; i++)\n \t\t{\n \t\t\tawait Task.Delay(10);\n \t\t\tNotify(i);\n \t\t}\n\n \t\treturn "complete";\n \t}\n }

This website uses Google Analytics. If you want to disable it just unselect the option: