Linux 上の .NET: 見た目よりもシンプル

公開: 2022-08-16

Linux で .NET ソリューションを開発することは、Microsoft の Visual Studio が動作するために Windows を必要とするため、常に困難でした。 いくつかの .NET プロジェクトに取り組んだ後、Linux での .NET 開発の限界をテストすることにしました。 この簡単なチュートリアルでは、SQL Server を使用した ASP.NET MVC アプリケーションに焦点を当て、好みの OS で .NET 開発がいかに洗練され効果的であるかを示します。

開発環境

まず、Microsoft の標準ガイドを使用して、特定の種類の Linux に関連する .NET ツールと SDK がインストールされていることを確認する必要があります。

私の好みの開発環境は、ウィンドウ化された統合開発環境 (IDE)、強力なデータベース管理およびクエリ ツール、データベース自体、および構築と展開のためのツールで構成されています。 次のツールを使用して、確実な機能を実現し、美しいコーディング体験を実現します。

  • IDE: ビジュアル スタジオ コード
  • データベース管理およびクエリ ツール: DBeaver
  • データベース: Microsoft SQL Server (Linux インストール)
  • ビルド ツール: .NET SDK コマンド ライン インターフェイス (CLI)
  • 仮想マシンとコンテナー: Docker

サンプル アプリケーションに進む前に、これらのツールが正しくインストールされていることを確認してください。

プロジェクトの足場

このサンプル アプリケーションでは、架空の靴屋の在庫管理システムの一連のユース ケースを通じて、ASP.NET の開発と機能を強調します。 新しい .NET アプリケーションと同様に、ソリューションを作成し、それにプロジェクトを追加する必要があります。 .NET SDK CLI ツールを活用して、新しいソリューションを足場にすることができます。

 mkdir Shoestore && cd Shoestore dotnet new sln

次に、簡単にするために、明示的なメイン クラスを含む ASP.NET プロジェクトを作成します。このプロジェクト構造は、ASP.NET 開発者にとって最もなじみ深いものです。 MVC パターンを使用してプロジェクトを作成しましょう。

 mkdir Shoestore.mvc && cd Shoestore.mvc dotnet new mvc --use-program-main=true

次に、プロジェクトをソリューションに追加します。

 # Go to the root of the solution cd .. dotnet sln add Shoestore.mvc/

これで、既定のソリューションとそれに含まれる ASP.NET プロジェクトができました。 先に進む前に、すべてがビルドされていることを確認してください。

 cd Shoestore.mvc/ dotnet restore dotnet build

優れた開発プラクティスでは、主要なサービスとアプリケーション ランタイムを Docker コンテナーに配置して、展開と移植性を向上させることが推奨されます。 したがって、アプリケーションをサポートする単純な Docker コンテナを作成しましょう。

アプリケーションの移植性

通常、Docker イメージは別の親 Docker イメージを、OS やデータベースなどの基本的なソリューションなどの必須要件の受け入れられた開始点として参照します。 この Docker のベスト プラクティスに従って、Microsoft が公開した親イメージを参照しながら適切なサービス構成を行うために、Dockerfile と Docker Compose ファイルの両方を作成します。 イメージを小さく保つために、Docker ステージを使用します。 ステージを使用すると、アプリケーションのビルド中に .NET SDK を使用できるため、アプリケーションの実行中にのみ ASP.NET ランタイムが必要になります。

以下の内容で、 Shoestore.mvc Dockerfile を作成します。

 # Shoestore\Shoestore.mvc\Dockerfile # Build stage FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /shoestore COPY Shoestore.mvc/*.csproj ./ # Restore project packages RUN dotnet restore COPY Shoestore.mvc/* ./ # Create a release build RUN dotnet build -c Release -o /app/build # Run the application and make it available on port 80 FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app EXPOSE 80 # Assets and views COPY Shoestore.mvc/Views ./Views COPY Shoestore.mvc/wwwroot ./wwwroot COPY --from=build /app/build ./ ENTRYPOINT [ "dotnet", "Shoestore.mvc.dll" ]

次に、ソリューションのルート ディレクトリにdocker-compose.ymlファイルを作成します。 最初は、アプリケーション サービスの.Dockerfileへの参照のみが含まれます。

 # Shoestore/docker-compose.yml version: "3.9" services: web: build: context: . dockerfile: Shoestore.mvc/Dockerfile ports: - "8080:80"

また、.dockerignore ファイルを使用して環境を構成し、ビルド アーティファクトのみがイメージにコピーされるようにします。

アプリケーション サービスがスタブ化され、その実行環境を実行する準備が整ったので、データベース サービスを作成し、それを Docker 構成に接続する必要があります。

データベース サービス

Microsoft SQL Server を Docker 構成に追加するのは簡単です。特に、Microsoft が提供する Docker イメージを変更せずに使用しているためです。 次の構成ブロックをdocker-compose.ymlファイルの末尾に追加して、データベースを構成します。

 db: image: "mcr.microsoft.com/mssql/server" environment: SA_PASSWORD: "custom_password_123" ACCEPT_EULA: "Y" ports: - "1433:1433"

ここで、 ACCEPT_EULAはインストールが停止するのを防ぎ、 ports設定はデフォルトの SQL Server ポートが変換なしで通過できるようにします。 これにより、Compose ファイルにはアプリケーション サービスとデータベースの両方が含まれます。

アプリケーション コードをカスタマイズする前に、Docker 環境が機能することを確認しましょう。

 # From the root of the solution docker compose up --build

起動時にエラーが表示されないと仮定すると、不完全なサンプル アプリケーションは、ローカル アドレスhttp://localhost:8080で Web ブラウザーから利用できるはずです。

コード生成ツール

ここからは、アプリケーション コードをカスタマイズし、アプリケーション データが Microsoft SQL Server データベースに保持されるようにするという、楽しい部分に焦点を当てます。 Entity Framework (EF) と .NET SDK ツールの両方を使用して、アプリケーションをデータベースに接続し、アプリケーションのモデル、ビュー、コントローラー、および EF に必要な構成をスキャフォールディングします。

必要なツールを指定する前に、 tool-manifestファイルを作成する必要があります。

 # From the root of the solution dotnet new tool-manifest

次の簡単なコマンドを使用して、このファイルに EF および SDK ツールを追加します。

 dotnet tool install dotnet-ef dotnet tool install dotnet-aspnet-codegenerator

これらのツールが正しくインストールされていることを確認するには、 dotnet efを実行します。 ユニコーンが表示されたら、それらは正しくインストールされています。 次に、 dotnet aspnet-codegeneratorを実行して ASP.NET ツールをテストします。 出力は、一般的な CLI 使用ブロックである必要があります。

これで、これらのツールを使用してアプリケーションを作成できます。

MVC: モデル

アプリケーションを構築する最初のタスクは、モデルを作成することです。 このモデルは後でデータベースに追加されるため、プロジェクトに MS SQL Server と EF パッケージを含めます。

 cd Shoestore.mvc/ dotnet add package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.EntityFrameworkCore.Tools dotnet restore

次に、データベースに追加するモデルを決定する EF データベース コンテキスト オブジェクトを作成し、コードがデータベースからそのデータに簡単にアクセスしてクエリできるようにします。

EF 固有のコードを格納するDataディレクトリを作成し、次の内容でData/ApplicationDBContext.csファイルを作成します。

 // Shoestore/Shoestore.mvc/Data/ApplicationDBContext.cs using Microsoft.EntityFrameworkCore; namespace Shoestore.mvc.Data; public class ApplicationDBContext : DbContext { public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options):base(options){} }

次に、データベース接続文字列を構成します。これは、 Dockerfileで構成した資格情報と一致する必要があります。 Shoestore/Shoestore.mvc/appsettings.jsonの内容を次のように設定します。

 { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "Shoestore": "Server=db;Database=master;User=sa;Password=custom_password_123;" } }

データベース接続文字列を構成し、データベース コンテキストをコーディングしたら、アプリケーションのMain関数をコーディングする準備が整いました。 システムのデバッグを簡素化するために、データベースの例外処理を含めます。 さらに、生成されたコードの .NET バグにより、Docker コンテナーがビューを正しく提供しないため、ビュー サービス構成に特定のコードを追加する必要があります。 これにより、Docker イメージ内のビューの場所へのファイル パスが明示的に設定されます。

 using Microsoft.EntityFrameworkCore; using Shoestore.mvc.Data; namespace Shoestore.mvc; // ... public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Associate our EF database context and configure it with our connection string var connectionString = builder.Configuration.GetConnectionString("Shoestore"); builder.Services.AddDbContext<ApplicationDBContext>( options => options.UseSqlServer(connectionString)); // Middleware to catch unhandled exceptions and display a stack trace builder.Services.AddDatabaseDeveloperPageExceptionFilter(); // Add services to the container. // ASP.NET has a known issue where the final built app doesn't know where the view // files are (in the Docker container). // The fix is to specifically add view locations. builder.Services .AddControllersWithViews() .AddRazorOptions(options => { options.ViewLocationFormats.Add("/{1}/{0}.cshtml"); options.ViewLocationFormats.Add("/Shared/{0}.cshtml"); });

同じファイル内のIsDevelopment ifステートメントまでスキップして、開発モードのときにデータベース移行エンドポイントをシステムに追加します。 次のコードを使用して、 elseステートメントを追加します。

 // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { // Leave the contents of the if block alone. These are hidden for clarity. } else { app.UseMigrationsEndPoint(); }

次に、簡単なテストを実行して、新しいパッケージとソース コードの編集が正しくコンパイルされることを確認します。

 // Go to mvc directory cd Shoestore.mvc dotnet restore dotnet build

それでは、 Shoestore.mvc\Models\Shoe.csファイルを作成して、モデルに必要なフィールドを設定しましょう。

 namespace Shoestore.mvc.Models; public class Shoe { public int ID { get; set; } public string? Name { get; set; } public int? Price { get; set; } public DateTime CreatedDate { get; set; } }

EF は、関連付けられたモデル、そのコンテキスト ファイル、およびアプリケーション内の任意の EF コードに基づいて SQL を生成します。 SQL の結果は、必要に応じて変換され、コードに返されます。 Shoeモデルをデータベース コンテキストに追加すると、EF は MS SQL Server とアプリケーション間の変換方法を認識します。 データベース コンテキスト ファイル、 Shoestore/Shoestore.mvc/Data/ApplicationDBContext.csでこれを行いましょう。

 using Microsoft.EntityFrameworkCore; using Shoestore.mvc.Models; namespace Shoestore.mvc.Data; public class ApplicationDBContext : DbContext { public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options) { } private DbSet<Shoe>? _shoe { get; set; } public DbSet<Shoe> Shoe { set => _shoe = value; get => _shoe ?? throw new InvalidOperationException("Uninitialized property" + nameof(Shoe)); } }

最後に、データベース移行ファイルを使用してモデルをデータベースに取り込みます。 EF ツールは、データベース コンテキストとそれに関連付けられたモデル (つまり、 Shoe ) に基づいて、MS SQL Server に固有の移行ファイルを作成します。

 cd Shoestore.mvc/ dotnet ef migrations add InitialCreate

コントローラーとビューが配置されるまで、移行の実行を保留しましょう。

MVC: コントローラーとビュー

ASP.NET コード生成ツールを使用してコントローラーを作成します。 このツールは非常に強力ですが、特定のヘルパー クラスが必要です。 基本的なコントローラー構造とその EF 統合には、 Designスタイル パッケージを使用します。 これらのパッケージを追加しましょう:

 cd Shoestore.mvc\ dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design && \ dotnet add package Microsoft.EntityFrameworkCore.Design && \ dotnet restore

これで、デフォルトのコントローラーを作成するのは、次のコマンドを呼び出すのと同じくらい簡単です。

 cd Shoestore.mvc\ dotnet dotnet-aspnet-codegenerator controller \ -name ShoesController \ -m Shoe \ -dc ApplicationDBContext \ --relativeFolderPath Controllers \ --useDefaultLayout \ --referenceScriptLibraries

コード ジェネレーターがコントローラーを作成するとき、そのコントローラーの単純なビューも作成します。 MVC の基盤が完成したので、すべてを実行する準備が整いました。

移行とアプリケーションのテスト

通常、EF の移行は単純な作業ですが、Docker が関与する場合、プロセスはより複雑になります。 連載の次の記事では、これらの移行を Docker ソリューションで機能させるための非常に曲がりくねった道を探りますが、今のところは、移行を実行するだけです。

すべての構成ファイルと移行ファイルは、リポジトリに含まれています。 プロジェクト全体をローカル マシンにクローンして、移行を実行しましょう。

 git clone https://github.com/theZetrax/dot-net-on-linux.git cd ./dot-net-on-linux docker composer up

docker composer操作は、アプリケーションをビルドし、移行を実行して、.NET ランタイムで ASP.NET アプリケーションを起動します。 実行中のソリューションにアクセスするには、 http://localhost:8080/Shoesにアクセスしてください。

アプリケーション インターフェイスはシンプルですが、ビューからデータベースまで、すべての層で機能を発揮します。

Linux 上の .NET はそのまま動作します

ソリューションの概要については、完全なリポジトリを参照してください。 次の記事では、移行の詳細と、Docker イメージをスリムにするためのヒントとコツについて説明します。

Linux 上の .NET は単なる夢物語ではありません。実行可能な言語、ランタイム、および OS の組み合わせです。 Visual Studio で育った多くの開発者は、.NET CLI を十分に使用した経験がないかもしれませんが、これらのツールは効果的で強力です。

Toptal Engineering ブログの詳細情報:

  • ASP.NET Core を使用して ASP.NET Web API を構築する
  • Microsoft Stack が依然として実行可能な選択肢である 8 つの理由
  • キャッシュを使用して Web ファームで ASP.NET アプリのパフォーマンスを向上させる方法
  • .NET 開発者向けの Elasticsearch チュートリアル
  • Kubernetes とはコンテナ化と展開のガイド

Toptal Engineering Blog は、この記事で紹介したコード サンプルをレビューしてくれた Henok Tsegaye に感謝の意を表します。