C#で作成したメソッドを、ODCのServer Actionとして利用する機能。
OutSystems11でいうと、Extensionに相当する。
修正履歴
2023/10/01 InterfaceとClassのメソッド引数にデフォルト値を渡すことで、Service ActionのInput ParameterのIs MandatoryとDefault Valueに反映されることがわかった。それに伴う修正を行った
2023/11/27 テストAppの利用の項目を追記
環境情報
ODC Studio(Version 1.2.3)
OutSystemsExternalLibraries.SDK.1.4.0
.NET SDK 6.0
Microsoft Visual Studio Community 2022 (Version 17.7.4)
サンプル
後ほど追加
1. C#でLibraryを書く
Visual Studioでプロジェクトを作る
Class Libraryを作るということなので、プロジェクト テンプレートはC#の「クラス ライブラリ」を選択。
NuGetよりOutSystems.ExternalLibraries.SDKを参照する。
まず、プロジェクトを右クリック(プロジェクトは下のスクリーンショットで選択中の位置が該当)
「NuGet パッケージの管理(N)」メニューを選択。出てきたダイアログで、参照タブを開いて、「OutSystems.ExternalLibraries.SDK」を検索し、インストール。
プログラムを書く
Interfaceを書く
Interfaceには、ODCに提供するServer ActionのI/Fを定義する。
C#の慣習に従い、Interface名は「I<Class名>」とする(ここではコンポーネント名をJapaneseCalendarとする予定なので、IJapaneseCalendarとした)。またそのファイル名もInterface名に合致させる(同じく、IJapaneseCalendar.cs)。
定義したIntefaceには[OSInterface]属性を付与する。
OSInterfaceのDescriptionプロパティがLibraryのDescriptionに設定される。
using OutSystems.ExternalLibraries.SDK;
namespace JapaneseCalendarODC
{
[OSInterface(Description = "This External Logic provides actions to handle Japanese Calendar (Japanese Era) ")]
public interface IJapaneseCalendar
{
[OSAction(Description = "Get formatted text of the inputted text as Japanese Calendar.", ReturnName = "FormattecText")]
public string FormatDateAsJapaneseCalendar(DateTime OriginalDate, bool TreatFirstYearSpecially = false, bool MakeNumbersFullWidth = false);
[OSAction(Description = "Get era and year (in era) of specified Date.", ReturnName = "JapaneseCalendarYear")]
public JapaneseCalendarYear DateToJapaneseCalendarYear(DateTime OriginalDate, bool TreatFirstYearSpecially = false, bool MakeNumbersFullWidth = false);
}
}
このInterfaceはpublicにしておかないと、「The interface decorated with OSInterface 'JapaneseCalendarODC.IJapaneseCalendar' is not public. (OS-ELG-MODL-05004)」というエラーが出た。
Interfaceに定義するメソッドについて
Interface内のメソッドに[OSAction]属性を付与し、そのDescriptionプロパティを設定することで、Server ActionのDescriptionに反映させている。
また、放っておくと、Output Parameterの名前がメソッド名と一致してしまう。
そこで、[OSAction]のReturnNameプロパティを設定することで、Output Parameterの名前を変更できる。
I/Fとなるメソッドが使えるデータ型には以下の制約がある
- 基本データ型: string, int, long, bool, byte[], decimal, float, double, DateTime
- OSStructure属性が付与されたStruct
- 上記2種類のList (IEnumerableを実装したもの)
ActionのOutput Parameterについて。OutSystems 11のExtensionでは、C#メソッドのout付き引数だったが、ODCでは普通に戻り値を返す
その戻り値に複数の値を持たせたい場合はStructを定義して返す
Structを書く
publicにする。
Server ActionのI/Fに出すStructureは、C#上でStructとして作成し、[OSStructure]属性を付与する。フィールドには[OSStructureField]属性を付与。同じくDescriptionプロパティは設定する。
2番目のDateToJapaneseCalendarYearメソッドは以下のStructを返す。
using OutSystems.ExternalLibraries.SDK;
namespace JapaneseCalendarODC
{
[OSStructure(Description = "A structure that has Japanese era and year expressed in AD")]
public struct JapaneseCalendarYear
{
[OSStructureField(Description = "1: Meiji, 2: Taisho, 3: Showa, 4: Heisei, 5: Reiwa")]
public int Era;
[OSStructureField(Description = "Era expressed in Japanese")]
public string EraText;
[OSStructureField(Description = "Year expressed in AD")]
public int YearInEra;
[OSStructureField(Description = "Year expressed in AD in text format")]
public string YearInEraText;
}
}
Classを書く
publicにする
ここの記述方法は通常と変わらない(このコードでは別のクラスを使って記述しているので注意)。
using JapaneseCalendarODC.Library;
namespace JapaneseCalendarODC
{
public class JapaneseCalendar : IJapaneseCalendar
{
public JapaneseCalendarYear DateToJapaneseCalendarYear(DateTime OriginalDate, bool TreatFirstYearSpecially = false, bool MakeNumbersFullWidth = false)
{
var result = new JapaneseCalendarYear();
var calendar = new JapaneseCalendarLibrary(OriginalDate,
TreatFirstYearSpecially, MakeNumbersFullWidth);
result.Era = calendar.Era;
result.EraText = calendar.EraText;
result.YearInEra = calendar.YearInEra;
result.YearInEraText = calendar.YearInEraText;
return result;
}
public string FormatDateAsJapaneseCalendar(DateTime OriginalDate, bool TreatFirstYearSpecially = false, bool MakeNumbersFullWidth = false)
{
var calendar = new JapaneseCalendarLibrary(OriginalDate,
TreatFirstYearSpecially, MakeNumbersFullWidth);
return calendar.DateText;
}
}
}
2. ODC PortalにPublish
publish
Visual Studio上でソリューション(通常は画面右にあるソリューションエクスプローラー内で最上位に表示される)を右クリックし、「ターミナルで開く」を選択。
以下は、チュートリアルにあったコマンド例「dotnet publish -c Release -r linux-x64 --self-contained false」を実行してみたときの、出力(プログラムに起因する警告は省略してある)。
「bin\Release\net6.0\linux-x64\publish\」フォルダに結果が出力されていることがわかる。
PS C:\Users\test\source\repos\JapaneseCalendarODC> dotnet publish -c Release -r linux-x64 --self-contained false
MSBuild のバージョン 17.7.3+8ec440e68 (.NET)
復元対象のプロジェクトを決定しています...
C:\Users\test\source\repos\JapaneseCalendarODC\JapaneseCalendarODC\JapaneseCalendarODC.csproj を復元しました (327 ms)。
JapaneseCalendarODC -> C:\Users\test\source\repos\JapaneseCalendarODC\JapaneseCalendarODC\bin\Release\net6.0\linux-x64\JapaneseC
alendarODC.dll
JapaneseCalendarODC -> C:\Users\test\source\repos\JapaneseCalendarODC\JapaneseCalendarODC\bin\Release\net6.0\linux-x64\publish\
.NET SDKのpublishコマンドのオプションで利用しているものは以下の通り
- -c: 構成をDebug/Releaseのどちらで公開するか。Releaseを指定するのでRelease構成
- -r: ランタイムの指定。ランタイム識別子というもので、アプリケーションが実行される対象プラットフォームを指定する。linux-x64という指定は、linuxのデスクトップディストリビューション向けであるらしい
- --self-configured: .NETランタイムをアプリケーションと一緒に含めるか。falseを指定しているので、含めないということか
ODCにアップロード
新しいExternal Logicを作成するときの手順。登録済みのExternal Logicを更新するときは、登録済みのExternal Logicのページを開き、「Upload new revision」ボタンから。
- 「bin\Release\net6.0\linux-x64\publish\」フォルダを開き、その中身のファイルを選択し、zipファイルに圧縮する(作成したzipファイルのサイズは90MB未満の必要がある)
- ODC PortalでサイドバーからExternal Logicを選択
- 右上の「Create library」ボタンをクリック
- 「Browse」ボタンか、そのエリアへのドラッグ&ドロップで作成しておいたzipファイルをアップロードし、右上の「Continue」ボタンをクリック
- 自動的に一覧画面に戻るが、アップロード↓ファイルにエラーが無ければ、テーブルの上にアップロードしたzipファイル名が表示される。その右にある「Review file contents」ボタンをクリック
- 結果を確認して「Publish library」ボタンをクリック。[OSInterface]を付与したInterfaceのメソッドがAction、[OSStructure」を付与したStructがStructureにマッピングされているはず
- 結果確認。右下にPublishの進行状況が表示される。最後まで行くとPublication finishedになる
3. Publishした機能を利用する
Library
[OSInterface]を付与したInterfaceの名前がLibrary名にマッピングされている。
Action
[OSInterface]を付与したInterfaceに含まれるメソッドがActionにマッピングされる。
また、必須ではないがメソッドに[OSAction]属性を付与し、そのDescriptionプロパティを設定するとActionのDescriptionプロパティに、ReturnNameプロパティを設定するとActionのOutput Parameterの名前に設定される。
C#のメソッド定義においてデフォルト引数を渡しておくと、以下の通り、Is Mandatory=No、Default Value=C#のパラメータに設定したデフォルト引数、となる
対応するコード
public string FormatDateAsJapaneseCalendar(DateTime OriginalDate, bool TreatFirstYearSpecially = false, bool MakeNumbersFullWidth = false);
Structure
[OSStructure]を付与したStructが、Structureにマッピングされる。
同じく[OSStructure]のDescriptionプロパティを設定すると、ODCのStructureのDescriptionプロパティが設定される。
StructureのAttributeにもDescriptionを設定したい場合は、C#上でStructのメンバーフィールドに[OSStructureField]を付与し、そのDescriptionプロパティを設定する。
注意すべき事項
External Libraries SDK README - App architecture using external logicによると、External Logicで作成したServer Action実行は、内部的にはHTTPS通信で実現される。
OutSystems11のときはインメモリだったので、その差に注意する必要がある。
テストAppの利用
ODCのLibraryはRelese Libraryをするまでの間、他のAppやLibraryから使えない。
しかし、Appを1つテスト用のAppとして指定すると、そのAppだけはRelease前の機能も使える。
External Logicも扱いとしてはLibraryなのでこの機能を使える。
しかしその操作の起点が異なることに注意。
- Libraryの場合:LibraryをPublishしたときにテストAppを指定できる
- External Logicの場合:ODC Portal左のExternal logic > 目標のExternal logic > Version historyタブ > 右の「…」 > Try library in an app と選ぶとODC Studioが開き、テストAppを指定できる。