-
Notifications
You must be signed in to change notification settings - Fork 35
Integrate with .net program
ReoScript provides the ability to execute script in your application. It usually can be used in the following cases:
-
Application with script execution
Software with Macro or Script execution is required to be available for end-user. (like VBA in Excel)
-
Script to be ran under a native library that is provided by your Application
You have a library written in .NET Application, and you want to your end-user can use them by writing script.
-
Console Script Execution
Some batch process program, Daily build, File publish or something else. You are able to make extensions for ReoScript in .NET Application, and writing and running the script in console.
-
Download ReoScript binary or build source file. Add the following DLLs into reference list of your project.
Antlr3.Runtime.dll Unvell.ReoScript.dll
-
Import the following namespace
using Unvell.ReoScript;
-
Create ScriptRunningMachine and keep the instance
ScriptRunningMachine srm = new ScriptRunningMachine();
-
Run script from different source
-
Run script in text
srm.Run("console.log('hello world');");
-
Run script from internal resource
using(MemoryStream ms = new MemoryStream(Resources.script)) { srm.Load(ms); }
-
Run script from specified file
srm.Load("C:\\scripts\\main.rs");
-
Run script from specified stream (could be a network, or unzipped stream etc.)
srm.Load(new NetworkStream(...));
See ScriptRunningMachine.
-
There are two practices to integrate ReoScript into your application.
- Manual Mode (writing wrapper objects, properties or methods)
- Automatic Mode (using DirectAccess)
To connect the two worlds between script and .NET, the wrapper objects, properties and methods may be necessary to be written.
+-----------------------------------------------------+
| Script |
| +-------------------------------------------+ |
+--- | Wrapper objects, properties and methods | ---+ <--- You may have to do
| +-------------------------------------------+ |
| .NET Application |
+-----------------------------------------------------+
I called this as 'Manual Mode' because anything you want to provide for script are all controllable precisely. Your end-user can only uses the functions that you want to be used. This practice is more safer and stable than Automatic Mode, it is also recommended usage if you are planning to make script execution is available to your end-user.
To write wrapper objects, properties and methods, the following classes you may need to use in .NET Application.
- ObjectValue - Make your own customized object type
- ExternalProperty - Make any external property for an object which used in script
- NativeFunctionObject - Make native method extension for an object which used in script
Once the script execution context(ScriptRunningMachine) is created, ReoScript keeps an global object until the context is destroying. Global object can be understood as a root object in the context, all objects to be used in script should be added into global object firstly. Once the object(even a function) has been added into global object, it will be available to all scopes of functions in a context. (See GlobalObject)
If you want to add a function for script, you may create a NativeFunctionObject instance and add it into global object. For example:
ScriptRunningMachine srm = new ScriptRunningMachine();
srm["myfunc"] = new NativeFunctionObject("myfunc", (ctx, owner, args) => {
Console.WriteLine('myfunc called!');
});
Now use this function in script:
myfunc();
The text will be printed out in console:
myfunc called!
In ReoScript, everything even a function are objects, and one object can be added into another object as its property by a given name. For example:
var obj = new Object(); // create an object instance
var func = function() { }; // create an anonymous function
obj.myfunc = func; // set func into obj as its property (now it more likes a method)
See NativeFunctionObject.
All the objects, types, properties and methods which requested to use in script are all mapped to .NET Runtime automatically by ReoScript engine. In this Automatic Mode, the intermediate wrapper objects is unnecessary.
+-----------------------------------------------------+
| Script |
| +-------------------------------------------+ |
+--- | .NET Reflection / ReoScript Engine | ---+ <--- You don't have to do
| +-------------------------------------------+ |
| .NET Application |
+-----------------------------------------------------+
DirectAccess allows script to access the property of .NET object by .NET Reflection Technology. Although this feature can be a very simple way to integrate ReoScript, but it may also became a potential risk at script run-time. Unless you uses script inside your application, please consider about the Manual Mode as 'My Suggestion'.
(See more DirectAccess)
Although ReoScript provides DirectAccess mechanism to access .NET object directly, it is recommended that writing wrapper objects, properties and methods if you are planning to make script execution to be available for your end-user.
For example, assuming there is a .NET object with one method and property:
public class Application
{
public void Start() { ... }
public string Name { get; set; }
}
With DirectAccess, you would be able to call 'Start' method from script directly:
var app = new Application();
app.start();
Or access its property like:
app.name = 'stuff';
But if you reformed your .NET Application, like renaming method, the script will be unavailable. For usability it is recommended that writing wrapper method for your application and script.
-
Create wrapper object - create a class inheriting from ObjectValue, keep an instance of original object. And add methods that you want to provide for script.
public class ApplicationObject : ObjectValue { public Application Application { get; set; } public ApplicationObject() { // keep original instance this.Application = new Application(); // add wrapper method this["start"] = new NativeFunctionObject("start", (ctx, owner, args)=> { this.Application.Start(); }); } }
About function extension please see NativeFunctionObject.
-
Import this wrapper object type into script context
// prepare srm ScriptRunningMachine srm = new ScriptRunningMachine(); // import .Net type into srm srm.ImportType(typeof(ApplicationObject), "Application");
Then the Application class will be available to script.
var app = new Application();
app.start();