白猫のメモ帳

C#とかJavaとかJavaScriptとかHTMLとか機械学習とか。

.NET Framework(4.6.2)のコンソールアプリケーションを.NET(7)にマイグレーションしてみる

.NETのアプリケーションをLinux(Docker)で動かしたいのでマイグレーションをします。
.NET Coreからだったらそんなに変わらない気もするんですが、.NET Frameworkだとまぁまぁ困惑します。

.NET 7って?

そもそも.NET 7って何だろうってところから。
もともとはWindows専用の.NET Frameworkクロスプラットフォームの.NET Coreという構成でしたが、.NET Frameworkが4.8で開発終了して、.NET Core 3.1の次のバージョンが.NET 5という形で統合したみたいです。
.NET 4じゃなくて.NET 5なのは.NET Framework 4系との混同を避けたからとか。

以降は.NET 6、.NET 7、.NET 8(予定)と続いていくようです。
偶数がLTSなので現在は.NET 6が安定、.NET 7が最新という感じでしょうか。

とりあえずプロジェクトを作る

VisualStudioからコンソールアプリを選んで、

フレームワークに.NET 7.0を選ぶと、

なんともシンプルなProgram.csが作られます。

プロジェクトファイルもシンプル。

.NET 6からはProgram.csクラスとかMainメソッドとかはコンソールアプリテンプレートが勝手に作ってくれるらしいです。
そして暗黙的なusingによってももろもろもusingもなくなって本文だけ書けば動く。おー便利。
クラシックなのが良ければ「最上位レベルのステートメントを使用しない」にチェックを入れればよさそう。(ImplicitUsingsの設定は別…?)

発行してみる

プロジェクトを右クリックして発行を押すと発行のプロファイルが作られます。
プロファイル設定を細かく見るとこんな感じ。

ここでフレームワーク依存⇔自己完結とかが選べるし、ターゲットランタイムもいろいろ選べます。簡単マルチプラットフォーム
ここでlinux-x64とか選んで発行すれば、あとはもうdotnetコマンドでLinux上で動かせます。

App.configがないです

設定とか書きたいですが、App.configがなくなってしまいました。悲しい。
代わりにappsettings.jsonを使います。

まずプロジェクトファイルにNuget参照を足して、

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
  </ItemGroup>

こんな感じでjsonファイルを作って、

{
  "ConnectionString": "せつぞくもじれつ"
}

こんな感じで取れます。

var config = new ConfigurationBuilder().AddJsonFile("appsettings.json", true, true)
                                       .Build();
var conStr = config.GetValue<string>("ConnectionString");

デバッグ用で変えたいときとかはデバッグプロパティから環境変数を設定して

appsettings.Development.jsonとか作ってこう。

var environmentName = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
var config = new ConfigurationBuilder().AddJsonFile("appsettings.json", true, true)
                                       .AddJsonFile($"appsettings.{environmentName}.json", true, true)
                                       .Build();
var conStr = config.GetValue<string>("ConnectionString");

ログ機能も欲しいです

コンソールアプリなのでログ機能も欲しいところです。
.NETだとMicrosoft.Extensions.Loggingを使うのが簡単そうです。

またNuget参照を足して、

  <ItemGroup>
    (略)
    <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
  </ItemGroup>

こんな感じ。これでコンソールログとデバックログに書き出せます。

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole().AddDebug();
});
var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Hello, World!");

ファイル出力したいならNLogとかを使って、

  <ItemGroup>
    (略)
    <PackageReference Include="NLog.Extensions.Logging" Version="5.2.3" />
  </ItemGroup>

Nlog.configファイルを作って、

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">

  <targets>
    <target name="logFile" xsi:type="File" encoding="UTF-8" fileName=".\logfile.log" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="logFile" />
  </rules>
</nlog>

こんな感じ。

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole().AddDebug().AddNLog("NLog.config");
});
var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Hello, World!");

便利なような?

.NET Frameworkからだと結構違うところがありますが、実は.NET Core時代からあったものばかりですね。
結構基本的な機能がNugetになっててあれってなることがちょいちょいありました。
あと今回全然触れていないですが、C#自体のバージョンがだいぶ上がってるのでそっちでも変化が…。

次回は今回ごにょごにょした設定ファイルとかログ周りをいい感じにしてくれる汎用ホストという機能を触ってみます。