T4 でクラスやプロパティを自動生成する

Text Template Transformation Toolkit (T4) はテンプレート エンジンの一つで、主に Visual Studio で使われているものです。
これを使うと、ソースコードやデータの集合などのファイルを自動生成できます。

今回は例として、次のような Markdown を記述したら、
それに対応するクラスやプロパティを C# のソースコードとして生成することを考えます。

この Markdown の仕様を次のように定めます。

  • 空行は無視
  • 箇条書きでない行がクラス名
  • その下に続く箇条書きはプロパティ
    • 「- Type PropertyName」の形式
    • プロパティ名が省略された場合は、型名と同じ
  • クラス名およびプロパティ名は、PascalCase, camelCase のどちらを指定してもよい

以下では、このような .md ファイルを入力として、
プロパティおよびコンストラクターを持つ部分クラスを .cs ファイルに出力するように T4 で実装していきます。

まず、プロジェクトに上記の .md ファイルを追加しておきます。
そしてプロジェクトに「テキスト テンプレート (.tt)」 を追加します。

Add New Item

追加された .tt ファイルを、仕様に従って次のように実装します。

注意点は以下の通りです。

  • 初期状態では出力の拡張子が .txt になっているため、.cs に変更する
  • プロジェクト内のファイルのパスを取得するには、hostspecific="true" を指定して Host.ResolvePath メソッドを使う
  • <#= #> :テキストの出力
  • <# #> :コードを書ける、変数を使える
  • <#+ #> :メソッド、クラスなどを定義できる

.tt ファイルを保存したときに処理が実行されます。
または、.tt ファイルを右クリックして [カスタム ツールの実行] を選択すれば実行されます。

Run Custom Tool

これで、以下のように RecordTypes.cs が生成されます。

 

作成したサンプル

テストしたバージョン

  • Visual Studio 2017

参照

広告
カテゴリー: ツール. タグ: , . Leave a Comment »

.NET Core 向けビルド スクリプト

ビルド用 PowerShell スクリプトの Build Release (GitHub) を .NET Framework プロジェクト形式向けに提供していましたが、
今回は .NET Core プロジェクト形式向けのビルドツールを追加しました。

ツールの内容:

(1) Version 1up

アセンブリのバージョン (x.y.z の z の部分) を 1 だけ増加させます。
.NET Core プロジェクト形式では、プロジェクト ファイル (.csproj) でバージョンを書き換えます。

(2) Zip Release

プロジェクトを Release でビルドして、ZIP ファイルを作成します。
ビルド前にアセンブリのバージョンを増加させます。

(3) NuGet Packup

プロジェクトを Release でビルドして、NuGet パッケージを作成します。
ビルド前にアセンブリのバージョンを増加させます。

これらのツール (PowerShell スクリプト) を使う方法としては、Visual Studio の「外部ツール」に登録するのが便利だと思います。
前回にビルド用のスクリプトを Visual Studio の外部ツールに登録する方法について書きましたが、
.NET Core 版の手順も改めて以下に書いておきます。

セットアップ

Build-Release/Downloads (GitHub) からツールの最新版をダウンロードして任意のフォルダーに展開します。

Explorer

Visual Studio のメニューで [ツール] – [外部ツール] を選択して各スクリプトを追加していきます。

  • タイトル: 任意
  • コマンド: powershell.exe
  • 引数: -ExecutionPolicy Unrestricted "C:\scripts_folder\KTools.xxx.ps1"
  • 初期ディレクトリ: $(ProjectDir)
    • 右の ▶ ボタンで選択できる
    • Version 1up では $(SolutionDir) でもよい
  • 出力ウィンドウを使用: オン

External Tools

 

プロジェクトの作成

.NET Core 向けのプロジェクト テンプレートを選択してプロジェクトを作成します。

New Project

.NET Framework プロジェクトではバージョン番号などを AssemblyInfo.cs に記述しますが、
.NET Core プロジェクトではプロジェクト ファイル (.csproj) に記述します。
初期状態ではバージョンが設定されていない (その場合は 1.0.0 と判定される) ため、
プロジェクトのプロパティで [パッケージ バージョン] の値を設定しておきます。

Project Property

上記の設定をして保存すると、.csproj ファイルの <Version> に反映されます。

.csproj

なお、.NET Core のプロジェクト形式でも、

<TargetFramework>net45</TargetFramework>

のようにすれば .NET Framework をターゲットにすることができます。
詳細は .NET Core と .NET Standard を参照してください。

 

ツールの実行:

(1) Version 1up

対象のプロジェクト内のファイルを開いた状態で、メニューからスクリプトを選択すると実行されます。

External Tools Menu

実行すると、ログが Visual Studio に出力されます。

Version 1up Output

 

(2) Zip Release

同様に、メニューから Zip Release を実行します。
zip フォルダーに ZIP ファイルが作成されます。

Zip Release

 

(3) NuGet Packup

クラス ライブラリ プロジェクトを対象に NuGet Packup を実行します。
pkg フォルダーに NuGet パッケージが作成されます。

NuGet Packup

 

注意点

  • .NET Framework プロジェクト形式向けには NuGet 経由でプロジェクトに PowerShell スクリプトを追加する
    方法 (KTools.ZipRelease) も提供していますが、.NET Core プロジェクト形式では NuGet で同様の方法で追加できませんでした。

 

前回: ビルド用のスクリプトを Visual Studio の外部ツールに登録する

テスト済バージョン
Visual Studio 2017

参照
Build Release (GitHub)
外部ツールの管理
.nuspec File Reference for NuGet

カテゴリー: ALM, ツール. タグ: , . 3 Comments »

ビルド用のスクリプトを Visual Studio の外部ツールに登録する

以前にビルドして ZIP にする PowerShell スクリプトを作成しましたが、
そのときはプロジェクトごとに NuGet でインストールする方法を前提としていました。
今回は各スクリプトを Visual Studio の外部ツールとして登録する方法も便利だとわかったため、その利用手順を紹介します。

設定手順:

  • Build-Release/Downloads (GitHub) から最新版をダウンロードして、任意のフォルダーに PowerShell スクリプトを展開する
  • Visual Studio のメニューで [ツール] – [外部ツール] を選択して各スクリプトを追加する
    • タイトル: 任意
    • コマンド: powershell.exe
    • 引数: -ExecutionPolicy Unrestricted "C:\scripts_folder\KTools.xxx.ps1"
    • 初期ディレクトリ: $(ProjectDir)
      • 右の ▶ ボタンで選択できる
      • KTools.VersionIncrement.ps1 は $(SolutionDir) でもよい
    • 出力ウィンドウを使用: オン

ExternalTools

 

以上の設定で、「プロジェクト フォルダー上で PowerShell スクリプトを実行する」ためのメニューが
Visual Studio の [ツール] メニューに追加されました。
実行するには、対象のプロジェクトのファイルを開いているときにメニューからそれらを選択します。

ExternalTools-Menu

[出力ウィンドウを使用] がオンに設定されていると、ログが Visual Studio に出力されます。

ExternalTools-Output

ExternalTools-Zip

 

このように Visual Studio の外部ツールを利用することで、
バージョンアップ、Release ビルド、ZIP 作成が Visual Studio から簡単にできるようになりました。

このツールは .NET Framework プロジェクト形式向けに提供していますが、
次回は .NET Core プロジェクト形式向けのツールを追加します。

次回: .NET Core 向けビルド スクリプト

テスト済バージョン
Visual Studio 2017

参照
Build Release (GitHub)
外部ツールの管理
Visual Studioの外部ツール機能を活用してみよう
ビルドして ZIP にする PowerShell スクリプト

カテゴリー: ALM, ツール. タグ: , . 3 Comments »

URL エンコーディング

URL エンコーディングの定義と、それを扱うための .NET Framework のライブラリを検証しました。

パーセント エンコーディングと URL エンコーディング

パーセント エンコーディングとは、文字列を UTF-8 でエンコードし、各バイトをパーセント記号 % とその 16 進数を用いて表すことです。
例えば、"/""%2F" に、"あ""%E3%81%82" に変換されます。

URL エンコーディングとは、URI の中で使われている記号と混在しないように一部の文字列をパーセント エンコーディングにより
変換することです。両者の言葉を区別せずに使うこともあります。

URL エンコーディング

RFC 3986 では、文字は次のように分類されます。

  • 非予約文字
    • エンコードしなくても利用できる文字
    • アルファベット、数字、および 4 種類の記号 -._~
  • 予約文字
    • URI で意味を持つ記号
    • 18 種類の記号 !#$&'()*+,/:;=?@[]
  • その他の文字
    • エンコードが必要な文字
    • 11 種類の記号 " %<>\^`{|} 、その他のすべての文字 (日本語など)

URL エンコーディングは、主に次の 2 通りで利用されます。

  • URI の各セグメント (クエリ文字列を除く)
    • https://tempuri.org/messages/Hello%20World%21messagesHello%20World%21 の部分
    • 非予約文字以外をパーセント エンコーディング
      • ただし、Web フレームワーク個別の仕様により、パーセント エンコーディングしても使用を制限されることがある
  • URI のクエリ文字列や、POST などで送信するときの本文 (フォーム)
    • key=value&message=Hello+World%21keyHello+World%21 の部分
    • 非予約文字以外をパーセント エンコーディングし、さらに %20 (スペース) を + に変換
    • MIME タイプ application/x-www-form-urlencoded と定義されている

 

.NET Framework のライブラリ

.NET Framework では、URL エンコーディングのために次の方法が用意されています。

  • System.Uri.EscapeDataString メソッド
    • RFC 3986 に従って非予約文字以外をパーセント エンコーディング
  • System.Uri.EscapeUriString メソッド
    • RFC 3986 に従って非予約文字・予約文字以外をパーセント エンコーディング
    • 既に全体が URI の形式になっているときに利用する
      • クエリ文字列も同様の規則で変換される。application/x-www-form-urlencoded には変換されない
  • System.Uri インスタンスの AbsoluteUri プロパティ
    • 基本的に Uri.EscapeUriString メソッドと同じだが、下記の点が異なる
    • %XX の形式になっているかどうかで扱いが異なる
      • https://tempuri.org/%2https://tempuri.org/%252
      • https://tempuri.org/%25https://tempuri.org/%25 のまま
    • クエリ文字列でない部分の \/ に変換される
  • System.Net.WebUtility.UrlEncode メソッド
    • RFC 2396 (旧版) に近い仕様で非予約文字以外をパーセント エンコーディングし、さらに %20 (スペース) を + に変換
  • System.Web.HttpUtility.UrlEncode メソッド
    • System.Net.WebUtility.UrlEncode メソッドと同じだが、小文字になる
  • System.Net.Http.FormUrlEncodedContent クラス
    • key-value データをまとめて application/x-www-form-urlencoded に変換

 

Uri.AbsoluteUri

 

.NET では System.Uri.EscapeDataString メソッドSystem.Uri.EscapeUriString メソッド
System.Net.Http.FormUrlEncodedContent クラスを使えばよいでしょう。

アプリケーションから HTTP 接続をするために System.Net.Http.HttpClient クラスを使うことが多いと思いますが、
接続先の URI を string で渡しても、HttpClient の内部では Uri インスタンスで扱われます。
したがって、URI を HttpClient に渡す前に、セグメントもクエリ文字列も URL エンコーディングしておくのがよさそうです。

 

作成したサンプル

バージョン情報

  • .NET Framework 4.5

参照

カテゴリー: .NET Framework, サービス. タグ: , . Leave a Comment »

ASP.NET Core Web API の Tips

ASP.NET Core で Web API を利用する際の注意点や備忘録です。ほぼ箇条書きです。
ASP.NET Web API 版は以前に書きました。

ルーティング、コントローラーなど

ASP.NET Web API と細かい差異はありますが、説明は省略します。
公式解説を参照するとよいでしょう。

CORS

  • NuGet で Microsoft.AspNetCore.Cors をインストールする
  • Startup.cs で AddCors メソッドおよび UseCors メソッドを呼び出すことで機能を有効にする
    • AddMvc メソッドおよび UseMvc メソッドの前で呼び出す必要がある
    • コントローラー、アクションの単位では [EnableCors] を指定する

CORS が機能しているかどうかをテストするには、現在実行中のものとは異なるドメインを Origin ヘッダーに付加して API を呼び出します。
応答に Access-Control-Allow-Origin ヘッダーが含まれていれば OK です。

要求ヘッダー

Origin: https://tempuri.org

応答ヘッダー

Access-Control-Allow-Origin: *

ツールとしては Advanced REST client などを使えばよいでしょう。

公式解説: ASP.NET Core でのクロス オリジン要求 (CORS) を有効にする

ヘルプ ページ

コードの XML ドキュメントから、ユーザー向けのヘルプ ページを自動的に生成する機能です。
ASP.NET Core では、OpenAPI (Swagger) の .NET 向け実装である Swashbuckle を利用します。
API を呼び出すためのテスト UI も含まれていて便利です。

  • NuGet で Swashbuckle.AspNetCore をインストールする
  • プロジェクトのプロパティで、XML ドキュメントの出力を有効にする
  • Startup.cs で AddSwaggerGen メソッド、UseSwagger メソッドおよび UseSwaggerUI メソッドを呼び出すことで機能を有効にする

ソースコード: Startup.cs

  • ヘルプ ページの URI は既定で /swagger となるが、ルートに変更するには、RoutePrefix を空文字列に設定する
  • アクション メソッドの戻り値が IActionResult の場合、
    [ProducesResponseType(200, Type = typeof(string))] のように属性でデータの型を指定する
  • このサンプルではアセンブリ情報の値をタイトルなどに設定している

公式解説: Swashbuckle と ASP.NET Core の概要

フォーマット

ASP.NET Core Web API では、既定でテキスト (text/plain) と JSON が有効になっています。
テキストを無効にして XML を有効にするには、Startup.ConfigureServices メソッド内で次のようにします。

さらに、コントローラーまたはアクションに Produces 属性を指定することで、利用可能な Content-Type を制限することもできます。

[Produces("application/json", "application/xml")]

公式解説: ASP.NET Core Web API の応答データの書式設定

 

前回: dotnet コマンドによるビルド

作成したサンプル

バージョン情報

  • Microsoft.AspNetCore.All 2.0.8
  • Microsoft.AspNetCore.Cors 2.0.3
  • Swashbuckle.AspNetCore 2.5.0

参照

カテゴリー: .NET Core. タグ: , . 3 Comments »

dotnet コマンドによるビルド

前回の .NET Core と .NET Standard に引き続き、今回はコマンドラインでアプリやライブラリをビルドする方法を検証しました。
まず、ビルドに関連する dotnet コマンドの一覧を挙げます。
基本的にはプロジェクト フォルダー上で実行しますが、build や pack などは ソリューション フォルダー上でも実行できます。

  • dotnet restore
    • NuGet 参照を解決する
  • dotnet build
    • MSBuild.exe を実行する
    • 内部で restore する (ソースコードしかない状態でも実行できる)
  • dotnet msbuild
    • MSBuild.exe と同じ引数を指定する
    • 内部で restore しない (ソースコードしかない状態では失敗)
  • dotnet publish
    • publish フォルダーに発行する
    • 内部で build する (ソースコードしかない状態でも実行できる)
  • dotnet pack
    • NuGet パッケージを作成する
    • 参照先の DLL は含まれず、依存関係が設定される
    • 内部で build しない (ソースコードしかない状態では失敗)
  • dotnet clean
    • 前回のビルド結果を消去する
    • restore の結果は残る
  • dotnet run
    • ソースコードからアプリを実行する
    • 内部で build する
  • dotnet App1.dll
    • ビルド済みのアプリを実行する

 

以下、詳細について記述していきます。

dotnet msbuild と msbuild

dotnet msbuild と msbuild の動作は同じです。

dotnet msbuild /p:Configuration=Release /t:Rebuild
msbuild /p:Configuration=Release /t:Rebuild

ただし、msbuild は環境変数の PATH に設定されていないため、
cmd や PowerShell で実行するにはそのパスを指定しなければなりませんが、
dotnet は PATH に設定されているため cmd や PowerShell でそのまま実行できて便利です。

アセンブリのビルド・発行

リビルドするには --no-incremental を指定します。

dotnet build -c Release --no-incremental

ただし build では、.NET Core を対象とする場合、NuGet 参照の DLL がコピーされません。
build では開発環境が想定されており、.dev.json ファイルに NuGet 参照が記述されます。
(.NET Framework を対象とする場合は NuGet 参照の DLL もコピーされます。)

配置用にすべての DLL を含めるには publish を使います。
プロジェクトに対象のフレームワークが複数ある場合、-f で一つだけ指定します。

dotnet clean -c Release
dotnet publish -c Release -f netcoreapp2.0

なお、publish 単独ではリビルドができないため、先に clean を実行しています。

NuGet パッケージ作成

出力先のディレクトリを変更するには -o を指定します。

dotnet pack -c Release -o pkg

または、

dotnet msbuild /p:Configuration=Release /t:pack

[構築時に NuGet パッケージを生成する] (.csproj では GeneratePackageOnBuild) を設定して build する方法もあります。

dotnet build -c Release --no-incremental

GeneratePackageOnBuild

 

前回: .NET Core と .NET Standard
次回: ASP.NET Core Web API の Tips

作成したサンプル

バージョン情報

  • .NET Core 2.0

参照

カテゴリー: .NET Core, .NET Framework, ツール. タグ: . 2 Comments »

.NET Core と .NET Standard

.NET Core の登場以降、Visual Studio で新しいプロジェクトを作成しようとすると、
従来の .NET Framework のほかに .NET Core と .NET Standard 向けのプロジェクト テンプレートが現れます。

NewProject

それぞれのプロジェクトにおけるアセンブリの参照可否をまとめると次のようになります。

  • .NET Framework 向けプロジェクト
    • .NET Framework アセンブリを参照可能
    • .NET Core アセンブリを参照不可
    • .NET Standard アセンブリを参照可能
  • .NET Core 向けプロジェクト
    • .NET Framework アセンブリを参照不可
    • .NET Core アセンブリを参照可能
    • .NET Standard アセンブリを参照可能

.NET Framework と .NET Core はランタイムが異なるため、
両方に対応するクロスプラットフォームのクラス ライブラリを作成するには .NET Standard をターゲットにします。
なお、.NET Standard 2.0 アセンブリは .NET Framework 4.6.1 以上で参照可能です。

.NET Core および .NET Standard のプロジェクト テンプレートには、次の特徴があります。

  • .csproj ファイルの記述が簡略化されている
    • アセンブリ情報は .csproj ファイルに含まれ、AssemblyInfo.cs は不要
  • NuGet パッケージを簡単に作成できる
    • ビルド時に作成するように設定できる

クラス ライブラリの .csproj ファイルの内容は次のようになっています。


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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

</Project>


TargetFramework を TargetFrameworks に変更すれば、対象のフレームワークをセミコロン区切りで複数指定できます。
ここで指定する netstandard2.0net40 は、Target Framework Moniker と呼ばれます。

<TargetFrameworks>netstandard2.0;net40</TargetFrameworks>

これで複数のフレームワークを対象にしたアセンブリを一度にビルドできます。

TargetFrameworks

.NET Framework 向けのみのアセンブリを作成したい場合であっても、
.NET Core 向けのテンプレートから作成して TargetFramework を変更する方法が有効です。

次に、OutputTypeExe を指定すればコンソール アプリになります (指定がなければクラス ライブラリ)。

<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net45</TargetFrameworks>

コンソール アプリをビルドすると、.NET Framework 向けでは .exe が生成されますが、.NET Core 向けでは .dll となります。
(自己完結型デプロイにより、各プラットフォーム向けの実行可能ファイルを生成することもできます。ただし 60MB 前後になります。)

NetCoreConsole

DLL の状態の .NET Core 向けアプリを実行するには、dotnet コマンドを実行します。

dotnet ConsoleApp1.dll

その他の注意点

  • 例えば System.Security.Cryptography 名前空間は .NET Standard で利用可能ですが、
    .NET Framework と .NET Core ではクラス構成に差異があります。
    ビルドできても実行時にエラーとなることもあります (HashAlgorithm.Create メソッドなど)。

 

次回: dotnet コマンドによるビルド

作成したサンプル

バージョン情報

  • Visual Studio 2017
  • .NET Core 2.0

参照