Edge.js
in-process interop with Node.js + .NET
(also, sry - not sry, memes aren't done)
Reasons not to use Node.js
Single threaded, event driven
Working with legacy tech?
You have existing components / knowledge of .NET
There's a superior implementation elsewhere
Reasons not to use C# / .NET
It's .NET
Not isomorphic (in the context of web dev)
Smaller package ecosystem / OSS community
You may have / need components that are already in Node
Less familiarity
\rightleftharpoons
⇌
Node.exe
MyService.exe
Node.exe
Edge.js
const edge = require('edge');
const helloWorld = edge.func(`
async (input) => {
return ".NET Welcomes " + input.ToString();
}
`);
helloWorld('JavaScript', (error, result) => {
if (error) throw error;
console.log(result);
});
const add7 = edge.func('async (input) => { return (int)input + 7; }');
var add7 = edge.func(function() {/*
async (input) => {
return (int)input + 7;
}
*/});
const add7 = edge.func(`
async (input) => {
return (int)input + 7;
}
`);
const add7 = edge.func(`
using System.Threading.Tasks;
public class Startup
{
public async Task<object> Invoke(object input)
{
int v = (int)input;
return Helper.AddSeven(v);
}
}
static class Helper
{
public static int AddSeven(int v)
{
return v + 7;
}
}
`);
const path = require('path');
const add7 = edge.func(path.join(__dirname, 'add7.cs'));
const clrMethod = edge.func({
assemblyFile: 'My.Edge.Samples.dll',
typeName: 'Samples.FooBar.MyType',
methodName: 'MyMethod' // This must be Func<object,Task<object>>,
references: [ 'System.Data.dll' ]
});
const clrMethod = edge.func('My.Edge.Samples.dll');
myFunction('Some input', (error, result) => {
//...
});
let result = myFunction('Some input', true);
Async
Synchronous
var dotNetFunction = edge.func('Edge.Sample.dll');
var payload = {
anInteger: 1,
aNumber: 3.1415,
aString: 'foo',
aBoolean: true,
aBuffer: new Buffer(10),
anArray: [ 1, 'foo' ],
anObject: { a: 'foo', b: 12 }
};
dotNetFunction(payload, function (error, result) { });
using System.Threading.Tasks;
public class Startup
{
public async Task<object> Invoke(dynamic input)
{
int anInteger = (int)input.anInteger;
double aNumber = (double)input.aNumber;
string aString = (string)input.aString;
bool aBoolean = (bool)input.aBoolean;
byte[] aBuffer = (byte[])input.aBuffer;
object[] anArray = (object[])input.anArray;
dynamic anObject = (dynamic)input.anObject;
return null;
}
}
const heavyLifting = require('edge').func(`
async (input) => {
// we are on V8 thread here
return await Task.Run<object>(async () => {
// we are on CLR thread pool thread here
await Task.Delay(5000); // simulate CPU bound
return "Done!";
});
}
`);
Multi-threading
const authenticate = require('edge').func(`
class Startup {
[DllImport("advapi32.dll")] static extern bool LogonUser(...);
public async Task<object> Invoke(dynamic i) {
IntPtr t;
return Startup.LogonUser(i.user, null, i.password, 3, 0, out t));
}
}
`);
authenticate({
user: 'satya@microsoft.com',
password: 'clippy4eva'
}, (error, result) => { ... });
Windows Auth
const convertImageToJpg = require('edge').func(`
#r "System.Drawing.dll"
using System.Drawing;
async (src) => {
await Task.Run(async () => {
Image.FromFile(src).Save((string)src + ".jpg", ImageFormat.Jpeg);
});
return null;
}
`);
convertImageToJpg('.\\edge.png', (error) => { ... });
Image Conversion
Symmetric
Other languages that compile to CLR
F#
Python
VB (lol)
Powershell
Lisp
Edge-ts
Typed bindings
Promises
Simple API for building from similar contexts
Search "edge-ts" on npm
simple.industries
acaprojects.com
edge.js
By Kim Burgess
edge.js
Node
- 191