1
0

.NET MAUIとCleanArchitectureで簡単なアプリを作成してみる4~実装2~

Last updated at Posted at 2024-01-22

.NET MAUIとCleanArchitectureで簡単なアプリを作成してみる4~実装1~の続き

Domainを実装する

新しいプロジェクトを追加する

種類「クラスライブラリ」
プロジェクト名「MauiApp1.Domain」
フレームワーク「.NET8」
フォルダ構成はフォルダ構成を決める(MauiApp1.Domain)の通り

エンティティを作成する

体調情報エンティティを作成する

Health.cs
    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インタフェースを作成する

IHealthRepository.cs
    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」を選択してインストールする
SQlite.PNG
「You need to call SQLitePCL.raw.SetProvider().」みたいなエラーになることがあるので、
「SQLitePCLRaw.bundle_e_sqlite3 2.1.7」もインストールする
SQlitePCL.PNG

DBを作成する

DBとテーブルを作成するコードをMauiApp1.SqlInfrastructure直下に作っておく

Sqlite.cs
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を実装する

HealthRepository.cs
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~

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0