.NET MAUIとCleanArchitectureで簡単なアプリを作成してみる4~実装1~の続き
Domainを実装する
新しいプロジェクトを追加する
種類「クラスライブラリ」
プロジェクト名「MauiApp1.Domain」
フレームワーク「.NET8」
フォルダ構成はフォルダ構成を決める(MauiApp1.Domain)の通り
エンティティを作成する
体調情報エンティティを作成する
public class Health
{
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="id"></param>
/// <param name="recordDate"></param>
/// <param name="heartNumber"></param>
public Health(int id, DateTime recordDate, int heartNumber)
{
Id = id;
RecordDate = recordDate;
HeartNumber = heartNumber;
}
/// <summary>
/// ID
/// </summary>
public int Id { get; }
/// <summary>
/// 記録日付
/// </summary>
public DateTime RecordDate { get; }
/// <summary>
/// ハート数
/// </summary>
public int HeartNumber { get; }
}
Repositoryインタフェースを作成する
public interface IHealthRepository
{
/// <summary>
/// 記録日付を指定して体調情報を取得する
/// </summary>
/// <param name="recordDate"></param>
/// <returns></returns>
Health? Find(DateTime recordDate);
/// <summary>
/// 期間を指定して体調情報を取得する
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
IEnumerable<Health> Find(DateTime startDate, DateTime endDate);
/// <summary>
/// 体調情報を保存する
/// </summary>
/// <param name="health"></param>
void Save(Health health);
}
便宜上、Interactorは後で作成します。
Infrastructureを実装する
新しいプロジェクトを追加する
種類「クラスライブラリ」
プロジェクト名「MauiApp1.SqlInfrastructure」
フレームワーク「.NET8」
フォルダ構成はフォルダ構成を決める(MauiApp1.SqlInfrastructure)の通り
「MauiApp1.Domain」をプロジェクト参照する
Sqliteをインストールする
NuGetからインストールします。
「Microsoft.Data.Sqlite.Core」を選択してインストールする
「You need to call SQLitePCL.raw.SetProvider().」みたいなエラーになることがあるので、
「SQLitePCLRaw.bundle_e_sqlite3 2.1.7」もインストールする
DBを作成する
DBとテーブルを作成するコードをMauiApp1.SqlInfrastructure直下に作っておく
using Microsoft.Data.Sqlite;
public static class Sqlite
{
/// <summary>
/// 接続文字列
/// </summary>
internal static string ConnectionString = "Data Source={0}";
/// <summary>
/// データベースを作成する
/// </summary>
/// <param name="db"></param>
public static void CreateDB(string db)
{
ConnectionString = string.Format(ConnectionString, db);
using (var connection = new SqliteConnection(ConnectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
// テーブルを作成する
command.CommandText = "CREATE TABLE IF NOT EXISTS Health ( id INTEGER NOT NULL PRIMARY KEY, record_date TEXT NOT NULL, heart_number INTEGER NOT NULL);";
command.ExecuteNonQuery();
}
}
}
}
Repositoryを実装する
using MauiApp1.Domain.Model.Healths;
using Microsoft.Data.Sqlite;
public class HealthRepository : IHealthRepository
{
/// <summary>
/// 記録日付を指定して体調情報を取得する
/// </summary>
/// <param name="recordDate"></param>
/// <returns></returns>
public Health? Find(DateTime recordDate)
{
using (var connection = new SqliteConnection(Sqlite.ConnectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM Health WHERE record_date = $record_date";
command.Parameters.AddWithValue("$record_date", recordDate);
var reader = command.ExecuteReader();
if (reader.Read())
{
return new Health(
(int)((long)reader["id"]),
recordDate,
(int)((long)reader["heart_number"])
);
}
else
{
return null;
}
}
}
}
/// <summary>
/// 期間を指定して体調情報を取得する
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public IEnumerable<Health> Find(DateTime startDate, DateTime endDate)
{
using (var connection = new SqliteConnection(Sqlite.ConnectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM Health WHERE record_date BETWEEN $start_date AND $end_date";
command.Parameters.AddWithValue("$start_date", startDate);
command.Parameters.AddWithValue("$end_date", endDate);
var reader = command.ExecuteReader();
var results = new List<Health>();
while (reader.Read())
{
DateTime.TryParse(reader["record_date"] as string, out DateTime recordDate);
var health = new Health(
(int)((long)reader["id"]),
recordDate,
(int)((long)reader["heart_number"])
);
results.Add(health);
}
return results;
}
}
}
/// <summary>
/// 体調情報を保存する
/// </summary>
/// <param name="health"></param>
public void Save(Health health)
{
using (var connection = new SqliteConnection(Sqlite.ConnectionString))
{
connection.Open();
// Idの有無を確認する
bool isExist;
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM Health WHERE id = $id";
command.Parameters.AddWithValue("$id", health.Id);
var reader = command.ExecuteReader();
isExist = reader.Read();
}
using (var command = connection.CreateCommand())
{
if (isExist)
{
// Idが存在する場合は更新する
command.CommandText = "UPDATE Health SET heart_number = $heart_number WHERE id = $id";
command.Parameters.AddWithValue("$id", health.Id);
command.Parameters.AddWithValue("$heart_number", health.HeartNumber);
}
else
{
// Idが存在しない場合は追加する
command.CommandText = "INSERT INTO Health(record_date, heart_number) VALUES($record_date, $heart_number)";
command.Parameters.AddWithValue("$record_date", health.RecordDate);
command.Parameters.AddWithValue("$heart_number", health.HeartNumber);
}
command.ExecuteNonQuery();
}
}
}
}
参考にしたURL
実践クリーンアーキテクチャ
Microsoft.Data.Sqlite 概要
まとめ
今回はDomain、Infrastructureを実装しました。
次はInteractorを実装します。
.NET MAUIとCleanArchitectureで簡単なアプリを作成してみる4~実装3~