0
0

[OutSystems]ODCでC#を取り込んでみる(External Logic)

Last updated at Posted at 2023-10-01

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#の「クラス ライブラリ」を選択。
image.png

フレームワークは、前提条件に従って.NET 6を選択。
image.png

NuGetよりOutSystems.ExternalLibraries.SDKを参照する。
まず、プロジェクトを右クリック(プロジェクトは下のスクリーンショットで選択中の位置が該当)
image.png

「NuGet パッケージの管理(N)」メニューを選択。出てきたダイアログで、参照タブを開いて、「OutSystems.ExternalLibraries.SDK」を検索し、インストール。
image.png

プログラムを書く

Interfaceを書く

Interfaceには、ODCに提供するServer ActionのI/Fを定義する。
C#の慣習に従い、Interface名は「I<Class名>」とする(ここではコンポーネント名をJapaneseCalendarとする予定なので、IJapaneseCalendarとした)。またそのファイル名もInterface名に合致させる(同じく、IJapaneseCalendar.cs)。

定義したIntefaceには[OSInterface]属性を付与する。
OSInterfaceのDescriptionプロパティがLibraryのDescriptionに設定される。

IJapaneseCalendar.cs
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を返す。

Struct.cs
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にする
ここの記述方法は通常と変わらない(このコードでは別のクラスを使って記述しているので注意)。

JapaneseCalendar.cs
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上でソリューション(通常は画面右にあるソリューションエクスプローラー内で最上位に表示される)を右クリックし、「ターミナルで開く」を選択。
image.png

以下は、チュートリアルにあったコマンド例「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」ボタンから。

  1. 「bin\Release\net6.0\linux-x64\publish\」フォルダを開き、その中身のファイルを選択し、zipファイルに圧縮する(作成したzipファイルのサイズは90MB未満の必要がある)
  2. ODC PortalでサイドバーからExternal Logicを選択
    image.png
  3. 右上の「Create library」ボタンをクリック
  4. 「Browse」ボタンか、そのエリアへのドラッグ&ドロップで作成しておいたzipファイルをアップロードし、右上の「Continue」ボタンをクリック
    image.png
  5. 自動的に一覧画面に戻るが、アップロード↓ファイルにエラーが無ければ、テーブルの上にアップロードしたzipファイル名が表示される。その右にある「Review file contents」ボタンをクリック
    image.png
  6. 結果を確認して「Publish library」ボタンをクリック。[OSInterface]を付与したInterfaceのメソッドがAction、[OSStructure」を付与したStructがStructureにマッピングされているはず
    image.png
  7. 結果確認。右下にPublishの進行状況が表示される。最後まで行くとPublication finishedになる
    image.png

3. Publishした機能を利用する

Library

[OSInterface]を付与したInterfaceの名前がLibrary名にマッピングされている。
image.png

Action

[OSInterface]を付与したInterfaceに含まれるメソッドがActionにマッピングされる。
また、必須ではないがメソッドに[OSAction]属性を付与し、そのDescriptionプロパティを設定するとActionのDescriptionプロパティに、ReturnNameプロパティを設定するとActionのOutput Parameterの名前に設定される。
image.png

C#のメソッド定義においてデフォルト引数を渡しておくと、以下の通り、Is Mandatory=No、Default Value=C#のパラメータに設定したデフォルト引数、となる
image.png

対応するコード

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プロパティを設定する。
image.png

注意すべき事項

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を指定できる。

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0