C#とNode.jsを連携する

###C#とNode.jsを連携する 

追記

[C#とNode.jsの連携の最終結論](https://qiita.com/iota_11/items/254e920cedc88182b110)

####EdgeJsを利用する
EdgeJsを利用しNode.jsからC#通信ができます。その逆もできます。.net4.6のみ。まだ.netCoreには未対応のようです。

#####Node.js側

```js
const edge = require('edge-js');

const helloWorld = edge.func('cs', function () {/*
    async (input) => { 
        return ".NET Welcomes " + input.ToString(); 
    }
*/});

helloWorld('Node.js', function (error, result) {
    if (error) throw error;
    console.log(result);
});
```
#####C#側
NodeJsからC#のメソッドを実行しデーターを渡します
<img width="500" alt="Screenshot from 2021-10-16 22-23-45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/ab2c45ff-0dc5-ae17-2a7f-5fb98bb5e763.png">
####edgeJsライブラリ

現在は更新されていません。メンテナンスを引き継いだプロジェクトが別にあります。

https://github.com/tjanczuk/edge

```
npm install edge
```

edgeで読み込む

```
const edge = require('edge');
```
####フォークされたもの
現在も保守されている

https://github.com/agracio/edge-js

```
npm install edge-js
```
edgeの後ろに-jsを付ける

```
const edge = require('edge-js');
```

####説明
https://www.npmjs.com/package/edge-js


#####Node.jsにインストールされたモジュールを表示する

```
npm list
npm -v
```

####環境構築
DockerFileの内容をみて必要なライブラリをインストールします。
Monoは必要ないです。

https://github.com/agracio/edge-js/#building-on-linux

####RiderのエディタからedgeJSモージュールをインストールする
npm install後にエディタ上で
波線をクリックするとnode_moduleフォルダが生成され、edgeモジュールがインストールされる

<img width="300" alt="Screenshot from 2021-10-16 21-54-49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/733c10cf-361b-361e-f0c8-a293fbd40043.png">

####動作に必要な設定

| コマンド | 有無 | 値 | 備考 |
|:-----------|:------------:|:------------:|:------------:|
| EDGE_USE_CORECLR       | 必須        | 1         | .NetCore用のedgeモジュールを利用する         |
| EDGE_NATIVE     | 必須      | edge-js/build/Release/edge_coreclr.node       |   相対パスで設定する 絶対パスだとエラーが出る     |
| EDGE_DEBUG     | オプション      | 1       | デバッグ表示       |
| EDGE_APP_ROOT     | オプション      | Publishフォルダへのパス        | 外部Dll Nugetライブラリを利用する時に使う　相対パスで設定する     |

####環境変数の設定の仕方

#####ターミナルから設定し実行する

```
EDGE_NATIVE=edge-js/build/Release/edge_coreclr.node EDGE_USE_CORECLR=1 EDGE_DEBUG=1 node test.js
```
#####RiderのNode.js設定画面から設定する
EnviromentValueで設定します。
<img width="500" alt="Screenshot from 2021-10-16 21-31-35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/4763f8ee-6f55-398d-18cb-0b8699ca5f4f.png">

#####JSプログラムの中に書く
```js
var path = require('path');

const baseNetAppPath = path.join(__dirname, '/bin/Release/netstandard2.0/publish/');

process.env.EDGE_USE_CORECLR = 1;
process.env.EDGE_DEBUG=1;
process.env.EDGE_NATIVE='edge-js/build/Release/edge_coreclr.node';
//process.env.EDGE_APP_ROOT = baseNetAppPath;
var edge = require('edge-js');
```

####サンプルを実行
node_modules/edge-jsフォルダの中にSampleファイルがあり、いろいろ試せます。

<img width="200" alt="Screenshot from 2021-10-16 22-47-09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/f6269408-dc26-d279-0f14-a708218e0675.png">

####デバッグ　3種類
####C#側のデバッグ
実行ボタンでデバッグ
<img width="50" alt="Screenshot from 2021-10-16 21-55-00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/30e231cb-a8cf-5cdc-02ce-ce0b4b7179a4.png">
エラーが緑文字で出る。C#側のCSファイルビルド状態、Dllファイルが読み込まれたかどうか Dllファイルがあるかアセンブリが読み込まれたかどうかなどいろいろ確認できます。
<img width="550" alt="Screenshot from 2021-10-16 21-55-52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/357b4478-241c-f53c-e0ff-b038efbd1325.png">
#####Node.js側のデバッグ
虫のアイコンでNode.js側がデバッグできます。Js側でブレイクポイントなどをしてデバッグします。
<img width="50" alt="Screenshot from 2021-10-16 21-55-09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/49e368ff-4f9d-849c-bbe5-a898d548ecaa.png">
edge.jsを追加するとブレイクポイントでデバッグできるようになる
<img width="200" alt="Screenshot from 2021-10-16 21-57-26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/061c3797-ecfe-6cbe-3591-f6fee93a2fff.png">
ブレイクポイント追加する
<img width="400" alt="Screenshot from 2021-10-16 21-56-54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/ec2f0d71-b76b-3975-387b-9af234de6d2d.png">

Debugger ConsoleとProcess Consoleでエラーログを見ることができます。
<img width="700" alt="Screenshot from 2021-10-17 16-07-03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/e6b0ab7c-a620-bcd8-141c-aa9de4731e0b.png">

####よく出るエラー

```
Uncaught TypeError: edge.initializeClrFunc is not a function
```

<img width="400" alt="Screenshot from 2021-10-16 22-56-11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/be264302-b54c-1426-3e07-54c5fbb9c508.png">
<img width="200" alt="Screenshot from 2021-10-16 22-54-51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/16b73d1b-c54d-10e2-50c7-6653eb900104.png">
一見JavaScript側のエラーのように見えるがC#側のエラーであることが多いです。C#側を確認するとよいです。

```
Error occurred during CoreCLR initialization
node:internal/modules/cjs/loader:1168
return process.dlopen(module, path.toNamespacedPath(filename));
```
<img width="500" alt="Screenshot from 2021-10-17 16-38-29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/248fd9dd-d6d5-104b-ba6b-3ae6d97ee695.png">
パスのどれかに絶対パスが含まれていると出るエラーになります。相対パスに直すと通ります。
環境変数の設定などで起きる

###ダイナミックライブラリの中に外部DllやNugetライブラリを利用する設定

プロジェクトフォルダに以下の値を追加する。

```
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="EdgeJs">
      <HintPath>..\..\node_modules\edge-js\lib\bootstrap\bin\Release\netcoreapp1.1\EdgeJs.dll</HintPath>
      <Private>true</Private>
    </Reference>
  </ItemGroup>
</Project>
```
.NET5のところをクリックしAdd FromからもDllを追加できます
<img width="500" alt="Screenshot from 2021-10-16 22-45-40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/64a35c34-e4bf-d950-d8d7-6139fe986715.png">

####Publishを設定する
Publishを実行すると依存ファイル(dllなど)、Nugetから入れたDLLをすべて同じフォルダに書き出せます。
<img width="500" alt="Screenshot from 2021-10-16 22-26-05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/ea9481bd-b6e3-5d54-5b97-9e70db5a16cd.png">

Publishフォルダへパスを通す。相対がよいです。

```
process.env.EDGE_APP_ROOT = '';
```
####Nugetから必要ライブラリをインストール
```
Microsoft.NETCore.DotNetHost 
Microsoft.NETCore.DotNetHostPolicy
```
このライブラリには既に依存ファイルが設定されています

https://github.com/agracio/edge-js-quick-start

####現在の状態　Dllファイルへのアクセス
サンプルファイルのDllへはアクセスができましたが、DLLプログラムのの中にNugetのライブラリを入れると読み込まれない状態です。
DapperやMicoroSoftのSqliteライブラリなどが読み込まれない。NewtonSoftのJesonのライブラリは読み込め使えました。
EDGE_APP_ROOTにPublishまでの相対パスを通すとエラーが起きます。
読み込み方法がわかる方ご教授ください。


####参考
https://qiita.com/yamachu/items/36da0b89f8ba75143643

[EdgeJsをC#のソースコードからデバッグする](https://qiita.com/iota_11/items/33b25369f13435aff999)に続く