ASP.NET Core appsettings.jsonを別プロジェクトで読み込む
ASP.NET Core DBの接続文字列を設定ファイルから取得するで、appsettings.json
に定義した接続文字列を読み込む方法を紹介しました。
しかし、実際は接続文字列はASP.NET Core
のプロジェクトではなくデータアクセス層やインフラ層などの別プロジェクトで読み込むことが多いです。
ここでは、ASP.NET Core ソリューションを作成して複数のプロジェクトを管理するで作成したソリューションにインフラ層のクラスライブラリのプロジェクトを追加して、そのプロジェクトで設定ファイルから接続文字列を取得するように実装します。
インフラ層の作成
以下のコマンドでインフラ層のプロジェクトを作成します。
$ dotnet new classlib -o App.Infrastructure
以下のフォルダが作成されます。
- App.Infrastructure ←作成される
- App.Web
- App.sln
本来はインフラ層だけではなくアプリケーション層やドメイン層も作成することが多いですが、ここでは説明の都合でインフラ層のみ作成しています。
ソリューションの追加
インフラ層のプロジェクトをソリューションに追加します。
以下のコマンドで、App.Infrastructure
プロジェクトをソリューションに追加します。
$ dotnet sln add App.Infrastructure
また、Web
層のプロジェクトに、インフラ層のプロジェクトを参照に追加します。
$ cd App.Web # Web層のプロジェクトに移動
$ dotnet add reference ../App.Infrastructure
パッケージのインストール
設定ファイルを読み込むためのパッケージをインフラ層のプロジェクトにインストールします。
- Microsoft.Extensions.Configuration
- 設定ファイルを読み込みためのパッケージ
- Microsoft.Extensions.Options.ConfigurationExtensions
- DI(Dependency Injection)を行うためのパッケージ
$ cd App.Infrastructure # インフラ層のプロジェクトに移動
$ dotnet add package Microsoft.Extensions.Configuration
$ dotnet add package Microsoft.Extensions.Options.ConfigurationExtensions
設定内容を格納するクラスの作成
接続文字列などの設定情報を格納するクラスを作成します。
インターフェースを作成して、そのインターフェイスを実装する形で作成します。
コンストラクタで接続文字列を受け取るようにして、ローカル変数に保持します。
GetConnectionString
メソッドで外部から接続文字列をアクセスできるようにします。
IDatabaseConfig.cs
namespace App.Infrastructure.Core;
public interface IDatabaseConfig
{
public string GetConnectionString();
}
DatabaseConfig.cs
namespace App.Infrastructure.Core;
public sealed class DatabaseConfig : IDatabaseConfig
{
private readonly string _connectionString;
public DatabaseConfig(string connectionString)
{
_connectionString = connectionString;
}
public string GetConnectionString() => _connectionString;
}
DIクラスの作成
DI
の設定を行うクラスを作成します。
AddInfrastructure
のファンクションは、ASP.NET Core
のプロジェクトから呼ばれます。
DIコンテナを管理するservices
と設定情報を管理するconfiguration
をパラメータとして受け取り、設定ファイルの読み込みや、DIコンテナへの追加を行います。
DependencyInjection.cs
using App.Infrastructure.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace App.Infrastructure;
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
// 接続文字列をパラメータにDatabaseConfigクラスのインスタンスを作成し、DIコンテナに追加する
services.AddScoped<IDatavaseConfig>(_ => new DatabaseConfig(configuration.GetConnectionString("DefaultConnection") ?? ""));
return services;
}
}
Web層のProgram.cs
で、上記のファンクションを実行するように、処理を追加します。
Program.cs
using App.Infrastructure;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddInfrastructure(builder.Configuration);
これにより、IDatabaseConfig
は設定ファイルの接続文字列をパラメータにインスタンス化されたものとして、各処理で参照することができます。
参照方法
ASP.NET Core DBの接続文字列を設定ファイルから取得するの処理をIDatabaseConfig
を参照するように書き換えます。
コンストラクタインジェクションで、DIコンテナに登録したクラスを参照します。
using App.Infrastructure.Core;
private readonly ILogger<WeatherForecastController> _logger;
private readonly IConfiguration _configuration;
private readonly IDatabaseConfig _databaseConfig;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
public WeatherForecastController(ILogger<WeatherForecastController> logger, IDatabaseConfig databaseConfig)
{
_logger = logger;
_configuration = configuration;
_databaseConfig = databaseConfig;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
using var conn = new NpgsqlConnection(_configuration.GetConnectionString("DefaultConnection"));
using var conn = new NpgsqlConnection(_databaseConfig.GetConnectionString());
今回は、データベースの設定情報のみインフラ層で定義するように修正しましたが、実際はDBアクセスクラスもインフラ層に実装することになります。
データアクセス関連の処理をすべてインフラ層に実装する方法をASP.NET Core DIできるDBクラスを作成してクリーンアーキテクチャを理解するで紹介しています。