It's Alive! Alive!: Apps That Create and Execute Other Apps
A few weeks ago we were talking to an iKnode user which was trying to write a code generator. While trying to help solve the problem, we came up with a solution that ended up being a really cool feature. Apps that Write other Apps.
We were already writing a service to allow iKnode Apps to call others, but to Create, Compile and Publish Applications from an iKnode Application was an amazing idea which would give iKnode Apps a lot more power and flexibility. We went ahead to spec, design and implement the feature. And today, we unveil the Frankestein Feature as we like to call it.
The iKnode engine is already implemented as a set of Services which are only accessible from the inside of our network. When an iKnode application runs, it is running inside our network, so it made sense to just allow iKnode Apps to just call our services. We created a service in the assembly iKnode.Applications (which is used by ALL iKnode Applications) to simplify the call to our internal service, allowing the caller to Save, Publish and Execute iKnode Applications.
Programming Interface
The Service is called “iKnode.Applications.ApplicationService” (docs) and handles “Application” (docs) objects. The Application class represents an application for the service. Let’s look at the structure:
The ApplicationService is the class that allows the application to perform operations in the iKnode engine. The structure is defined below:
The important operations for the Application Service are:
Save
Allows the Application to be Saved. There is not compilation or validation of code. A ‘Saved’ application is considered in Draft mode, which means it cannot be executed. Use this method to store partial or drafts of an application.
1 2 3 |
|
Publish
Allows the Application to published. The Application is first saved, then compiled and then published so that it can be executed. If there is any compilation errors, and exception will be generated. A successfully published Application can be Executed.
1 2 3 |
|
Execute
Executes the Application and returns the application result if any.
1 2 3 |
|
Remove
Removes an existing application even if the application has been published. If removal is successful the Application will not longer be available.
1 2 3 |
|
GetById
Returns the Application Information by using the Application Identifier. It will return null if not found.
1 2 3 4 |
|
GetByName
Returns the Application Information by using the Application Name. It will return null if not found.
1 2 3 |
|
Example
We have built an example that covers all of the operations. Throughout this example we will class this Application “The Host”. The host’s main purpose is to create the Guest Application if it doesn’t exist, and then run it. But if the application already exists then it sohuld only execute it.
The code for the Host is shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
|
What the Host application does is create another application named “Test” which performs a “Sum” operation. We will refer to the generated application as the Guest. The code this new Application will have is:
1 2 3 4 5 6 7 8 9 10 |
|
Let’s test the Host application. Before executing the Host, this is how the Application Library looks like:
If we execute the application the first time, this is what we will see:
As we can see the application was not found by the Host application and created it before executing it. If we run it a second time, this is what we’ll see:
As we can see the guest application was found, so it was just executed. If we go to the Application Library we’ll see the GuestApp, just like any other application.
We hope you enjoy this new feature, we had a lot of fun writing it and coming up with applications to use it. Try it and let us know what you think.