Linux 上の .NET: 見た目よりもシンプル
公開: 2022-08-16Linux で .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 に感謝の意を表します。