noxi雑記

.NET、Angularまわりの小ネタブログ

MicroBatchFrameworkを試す 1 - バッチの作成と実行、発行

業務で .NET の簡単なバッチを作る機会があり、どう作ろうかな、、、と悩んでいたときにふと思い出したので使ってみました。 ASP.NET Core で開発している資産を流用したいので CommandLineUtils と Microsoft Extensions 系( DI や Configurations 、 Logger )を使用するオレオレバッチフレームワークを作ってみたりもしましたが今一だったので、渡りに船というやつです。


試用環境

MicroBatchFramework の導入と発行

プロジェクトの準備

MicroBatchFrameworkを試すために、まずはソリューションとプロジェクトを作成します。 Visual Studio から作っても良いのですがサクッとコマンドプロンプトから作ります。

: 今回のプロジェクト用ディレクトリ作成
mkdir MicroBatchFrameworkSampe
cd MicroBatchFrameworkSample

: .NET SDKバージョン固定
dotnet new globaljson --sdk-version=2.2.202

:  ソリューション作成
dotnet new sln

: プロジェクト作成とソリューションへの追加
: バッチのエントリーポイントでasyncを使用するため言語バージョンをlatestに設定
dotnet new console -n BatchApp -o src/BatchApp --langVersion=latest
dotnet sln add src/BatchApp/BatchApp.csproj

: MicroBatchFrameworkを依存に追加
dotnet add src/BatchApp/BatchApp.csproj package MicroBatchFramework

これで MicroBatchFramework が組み込み済みのソリューションとプロジェクトが生成されます。作成されたプロジェクトは .NET Core 2.2 を使う設定になっていますが、 .NET Framework 向けにもビルドをしたい場合はプロジェクトファイルの TargetFramework を変更します。

src/BatchApp/BatchApp.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <!-- <TargetFramework>netcoreapp2.2</TargetFramework> -->
    <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MicroBatchFramework" Version="0.4.6-beta10" />
  </ItemGroup>

</Project>

TargetFrameworkTargetFrameworks に変更してビルド対象のフレームワークを複数個 ; で区切って記述すると、複数のフレームワーク向けにビルドを実行できます。 Visual Studio の画面上では変えられない気がするので、直接 CSPROJ ファイルをいじります。今回の例では .NET Core 2.2 と .NET Framework 4.6.1 向けの設定です。

ソリューションを Visual Studio で開く

コマンドプロンプトから作成したソリューションとプロジェクトを Visual Studio で開きます。
ソリューションファイルが Visual Studio に関連付けられている環境であれば開くはずです。 Visual Studio Code などが開いた場合は Visual Studio から直接ソリューションファイルを選択して開きましょう。

: ソリューションを開く
.\MicroBatchFrameworkSample.sln

正しく作成されていればこのようになります。

f:id:noxi515:20190407220714p:plain

HelloWorld を出力するバッチタスクを作成する

MicroBatchFramework を使用して Hello World 文字列を出力してみます。実装するには次の4つの手順を踏みます。

  1. BatchBase を継承したクラスを作成する。
  2. バッチの中身となる適当なメソッドを作成する。
  3. ProgramMain メソッドを async に変更する。
  4. ProgramMain メソッドを BatchHost を使用する形に変更する。

BatchBase を継承したクラスを作成する

まずは実行されるバッチの本体部分となるクラスを作成します。 Program.cs を開き HelloWorldBatch クラスを追加します。

using System;
using MicroBatchFramework;

namespace BatchApp
{
    class Program
    {
        ...
    }

    class HelloWorldBatch : BatchBase
    {
    }
}

バッチの中身となる適当なメソッドを作成する

次にバッチの中身(「Hello World」を出力する)を実装するためのメソッドを作成します。
メソッド名自体は何でも良いため、今回は RunAsync としました。

using System;
using System.Threading.Tasks;
using MicroBatchFramework;

namespace BatchApp
{
    class Program
    {
        ...
    }

    class HelloWorldBatch : BatchBase
    {
        public Task RunAsync()
        {
            Console.WriteLine("Hello World");
            return Task.CompletedTask;
        }
    }
}

ProgramMain メソッドを async に変更する

次にバッチプログラムのエントリーポイントとなる Main メソッドを async に変更します。

using System;
using System.Threading.Tasks;
using MicroBatchFramework;

namespace BatchApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }

    class HelloWorldBatch : BatchBase
    {
        ...
    }
}

ProgramMain メソッドを HostBuilder を使用する形に変更する

最後に Main メソッドの中身を HostBuilder を生成し、バッチを実行するように書き換えます。
非同期に実行されるため await を頭に付けるのを忘れずに。

using System;
using System.Threading.Tasks;
using MicroBatchFramework;
using Microsoft.Extensions.Hosting;

namespace BatchApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await BatchHost.CreateDefaultBuilder().RunBatchEngineAsync<HelloWorldBatch>(args);
        }
    }

    class HelloWorldBatch : BatchBase
    {
        ...
    }
}

バッチプログラムを発行して実行する

※ここから先はフレームワークとして .NET Core 2.2 を対象としています。

MicroBatchFramework で作成されたバッチを発行して実行するには2通りの方法があります。1つは .NET Core ランタイムがインストールされた環境向けに dll で実行ファイルを出力する方法、もう1つは .NET Core ランタイムも含めて exe ファイルを出力する方法です。

: ランタイムが含まれない dll の出力
dotnet publish -c release -f netcoreapp2.2 src\BatchApp\BatchApp.csproj
: 実行
dotnet src\BatchApp\bin\release\netcoreapp2.2\publish\BatchApp.dll

: ランタイム込みの exe の出力
dotnet publish -c release -f netcoreapp2.2 -r win-x64 src\BatchApp\BatchApp.csproj
: 実行
.\src\BatchApp\bin\release\netcoreapp2.2\win-x64\publish\BatchApp.exe

.NET Core ランタイムを含めて出力する方式ではOS環境毎に実行モジュールが異なるため、どのOS環境で実行するかをオプションで指定します。上の例は Windows の 64 ビット環境で実行するための exe を出力する場合です。 .NET Core ランタイムがインストールされていない環境でも実行できるメリットがある反面、実行ファイル数、ファイルの総バイト数はランタイムを含めないときと比較して大幅に増加します。
(※ファイル数 26 → 239 、ファイルサイズ合計 1.5MB → 67MB)

バッチプログラムに引数を設定する

メソッドの引数で指定する

MicroBatchFramework はバッチとして実行されるメソッドに引数を設定しておくと、それをそのままバッチプログラムの実行引数として扱います。先ほど実装したバッチプログラムは「Hello World」という固定文字列を出力するものでしたが、これを message 引数で指定した文字列を出力する様に変更してみます。

using System;
using System.Threading.Tasks;
using MicroBatchFramework;
using Microsoft.Extensions.Hosting;

namespace BatchApp
{
    class Program
    {
        ...
    }

    class HelloWorldBatch : BatchBase
    {
        public Task RunAsync(string message)
        {
            Console.WriteLine(message);
            return Task.CompletedTask;
        }
    }
}

これを引数無しで実行すると、引数リストが表示され、実行に失敗します。また help を付けて実行すると引数の一覧が表示されます。

dotnet src\BatchApp\bin\release\netcoreapp2.2\publish\BatchApp.dll
argument list:
-message: String

dotnet src\BatchApp\bin\release\netcoreapp2.2\publish\BatchApp.dll help
argument list:
-message: String

dotnet src\BatchApp\bin\release\netcoreapp2.2\publish\BatchApp.dll -message Hoge
Hoge

引数を指定しない場合のデフォルト値を設定したい場合、メソッドの引数にデフォルト値を設定することもできます。

バッチ引数の説明や ShortName を設定する

message 引数でバッチプログラムに対して表示する文言を指定できるようになったら、次はその引数に対して説明文や ShortName を設定してみます。 CommandLineUtils ではちょっと面倒だったこの設定が MicroBatchFramework では Option 属性をメソッドの引数に付けるだけです。

class HelloWorldBatch : BatchBase
{
    public Task RunAsync(
        [Option(shortName: "m", description: "表示する文言")] string message)
    {
        Console.WriteLine(message);
        return Task.CompletedTask;
    }
}

[Option] を設定した状態で実行するとこのように表示されます。

dotnet src\BatchApp\bin\release\netcoreapp2.2\publish\BatchApp.dll help
argument list:
-m, -message: 表示する文言

おわりに

この記事では MicroBatchFramework を使用したプロジェクトの作成と実行、発行について試してみたことを書いてみました。次の記事では設定ファイルを使ってみます。