20211010のC#に関する記事は7件です。

【Moq】Moq.VerifySet()を用いたExcel描画のテスト方法

Moqとは 型さえあれば未実装であってもMock(=ダミーの実装)を作ってくれる。 実装の出来不出来に関係なくテストを書ける。 Excelに描画するテスト 今のデータをExcelに描画する機能をClosedXMLを用いて実装しているのですが、ちゃんと描画されたか否か確認するのが少し大変です。 例えばサーバー側にExcelがあることを前提としている場合はClosedXMLの正式な実装を使ったときにLinuxサーバーなどのExcelがない環境では正しく実行されない。 そのため、なるべく環境に依存しないコードを書きたい。 そこで今回はMoqでClosedXMLのダミーを作り、そのダミーを使って自ら書いたプログラムが正しい挙動か確認します。 Mocking library for .NET 描画された文字が正しいか判定すテスト テストの流れは 1. テストしたいクラスの初期化 2. moqでClosedXMLのIF、実体クラスを生成 3. 生成したクラス・メンバーに値を入れた時の返り値を設定(ダミー実装) 4. 値を入れられることを確認(テスト) とします。 //確認したいメソッド //Renderの中では指定したsheetのrow,colに値を代入するだけとする class Renderer() { public void Render(sheet, row, col) { //例 sheet.Cell(row, col).Value = "糖質過多"; } } //テスト public class Test() { public void RenderTest() { //1. テストしたいクラスの初期化 var renderer = new Renderer(); //2. moqでClosedXMLのIF、実体クラスを生成 //MoqでClosedXMLのラッパークラスを作る var mockSheet = new Mock<IXLSheet>(); var mockeCell = new Mock<IXLCell>(); //Mock<T>.Objectで型引数の実態クラスを生成する var mockSheetObject = mockSheet.Object; //3. 生成したクラス・メンバーに値を入れた時の返り値を設定 //mockCell.Valueプロパティのsetterにstring型なら何でも代入できるようにする //Verifiable()でVerify()できるようにする mockCell.SetupSet(o => o.Value = It.IsAny<string>()).Verifiable(); //Setup()で引数とそれに対する返り値を設定する mockSheetObject.Setup(o => o.Cell(1, 30)).Returns(() => mockCell.Object); //4. 値を入れられることを確認(テスト) //mockSheetObectに上で指定した引数を渡す renderer.Render(mockSheetObject, 1, 30); //mockCell.Valueプロパティに"糖質過多"が代入できることを確認する mockCell.VerifySet(o => o.Value = "糖質過多"); } } これでテストは完了です。 使用したMoqの関数を一つずつ見ていきましょう Moqで使用した関数 Mock.Object モックオブジェクトを取得する。指定した型の実装クラスを作ってくれます。 Mock.InitializeInstance() Mock.Setup() Setup()は「実装する関数を準備する」関数です。 Mock.SetupSet() 返り値がVoidSetupPhrase<T> : SetupPhraseとなりこのSetupPhraseクラス内に引数の値(今回であればIXLCell Cell(row, col)の返り値)を保持します。 WherePhrase.SetupSet() Mock.SetupSet().Returns() SetupSet()ではSetupPhraseクラスに値を保持させましたが、Returns()ではその値を保持していた場合にどんな値を返すか設定します。 今回は引数(row: 1, col:30)が入力されたときの返り値はmockCell.Objectであると定義しています。 mockCellはIXLCellIFのダミー実装ですね。 SetupPhrase.Verifiable() It.IsAny() T型のダミーな値を返します。用法としては指定した型を受け入れるようになります。 今回はstring型の値であればどんな値でも代入できるようにしました。 It.IsAny().Verifiable() Verifiable()はSetupクラス内のプライベートなフラグをVerifyにします。 これによりテストでVerify()が使えるようになるようです。 フラグには他にOverridderとMatchedがあるようですがこれらの使われ方は追いきれませんでした。。ご存じでしたら教えて下さい。 enum Flags Setup.MarkAsVerifiable() Mock.VerifySet() ここまででSetterに値が代入されたかを判定する。代入されていなければ例外が投げられテストが通らない。 今回は実装クラス(Moqではない方)で”糖質過多”を代入しているのでテストパスとなる。 まとめ Verify~の関数を使えばvoidの関数をテストできるので便利ですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# リストのシャッフル

0.0 はじめに リスト(List)内の要素をシャッフルする方法を調べてみました。 1.0 スクリプトでシャッフル 下記のスクリプトでシャッフル可能です。 Shuffle.cs // リストlistをシャッフルする (for降順ランダム取り) for (int i = list.Count - 1; i > 0; i--){ var j = Random.Range(0, i+1); // ランダムで要素番号を1つ選ぶ(ランダム要素) var temp = list[i]; // 一番最後の要素を仮確保(temp)にいれる list[i] = list[j]; // ランダム要素を一番最後にいれる list[j] = temp; // 仮確保を元ランダム要素に上書き } 2.0 定型文を利用したシャッフル方法 OrderByを使うためにusing System.Linq、Guidを使うためにusing Systemを追加します。 Shuffle.cs // リストをランダムに並べ替える list = list.OrderBy(a => Guid.NewGuid()).ToList(); 配列の場合は下記でOKです。 array = array.OrderBy(a => Guid.NewGuid()).ToArray();
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity C# 自作Randamクラス

0.0 はじめに using Systemを追加したらRandamクラスはUnityEngineの明示が必要となります。 ほかにも方法がありますが、対策しないとエラーになります。 Systemとぶつからない様にするためのいろいろと検討しましたが、自作Randamクラス(Randクラス)を使うのが簡単でした。 1.0 スクリプト 以下はint, floatでランダムな数字を入手するための関数を入れています。 Rand.cs using UnityEngine; // using Systemを使ったときにぶつからない様にするための疑似Randamクラス public static class Rand{ /// <summary> /// minとmaxの間のランダムなintを返す。min含む、max含まない。 /// </summary> public static int Range(int min, int max) { return Random.Range(min, max); } /// <summary> /// minとmaxの間のランダムなfloatを返す。min含む、max含む。 /// </summary> public static float Range(float min, float max) { return Random.Range(min, max); } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】Missingチェックを行うEditor拡張

GameObjectに付与したスクリプトや、インスペクタウィンドウで設定したマテリアルや他のGameObjectへの参照がリンク切れになって「Missing」という表示になってしまうことってありますよね。 プレイ中に思ったように動かなくて調べたらMissingになっていたということがあるので、少しでも早く気付けるようにEditor拡張を作成しました。 バージョン2020.3.5f1で動作確認。 仕様 ヒエラルキーウィンドウに表示しているGameObjectに以下のものが存在する場合、対象GameObjectの行にワーニングアイコンを表示する。 付与されているコンポーネントにMissingなものが存在する場合。 SerializeField設定項目の中にMissingなものが存在する場合。 同時にコンソールにエラーメッセージを表示する。 GameObject単位で最初に発見したリンク切れ情報を表示する。 ポイント解説 下記の投稿と重複する部分は省きます。 コンポーネントへの参照がリンク切れになっているかを確認する方法 EditorApplication.hierarchyWindowItemOnGUIイベントに登録したイベントハンドラ内で、GameObjectに対してGetComponents<Component>()を行ってnullのものが存在する場合、そのコンポーネントはリンク切れとなっています。 コンポーネントへの参照がリンク切れになっているかを確認 private static void CheckMissingReference(int instanceID, Rect selectionRect) { // instanceIDをオブジェクト参照に変換 if (!(EditorUtility.InstanceIDToObject(instanceID) is GameObject gameObject)) return; // オブジェクトが所持しているコンポーネント一覧を取得 var components = gameObject.GetComponents<Component>(); // Missingなコンポーネントが存在する場合はエラー表示 var existsMissing = components.Any(x => x == null); if (existsMissing) { UnityEngine.Debug.LogError( gameObject.name + "のコンポーネントにMissingのものが存在します。"); } } SerializeFieldへの参照がリンク切れになっているかを確認する方法 SerializeFieldが以下の条件に当て嵌まる場合はリンク切れと見なすことができます。 SerializedPropertyのobjectReferenceValueがnull(=参照先が存在しない)なのに、FileIDは設定されている(=参照すべきものは設定されている)もの SerializeFieldへの参照がリンク切れになっているかを確認 var serializedProp = new SerializedObject(component).GetIterator(); while (serializedProp.NextVisible(true)) { if (serializedProp.propertyType != SerializedPropertyType.ObjectReference) continue; if (serializedProp.objectReferenceValue != null) continue; var fileId = serializedProp.FindPropertyRelative("m_FileID"); if (fileId == null || fileId.intValue == 0) continue; UnityEngine.Debug.LogError( component.name + "の" + component.GetType().Name + "のフィールド" + serializedProp.propertyPath + "がMissingとなっています。"); } ただし過去にUnityのバージョンアップで仕様が変更になったことがあるので、バージョンによっては他の方法が必要となるかもしれません。 ワーニングアイコン表示 ワーニングアイコンは以下の形で取得することができました。 アイコン名はこちらを参考にしましたが、Unityのバージョンによって変わるかもしれません。 ワーニングアイコン取得 Texture warningIcon = EditorGUIUtility.IconContent("console.warnicon").image; エラーメッセージ表示頻度 EditorApplication.hierarchyWindowItemOnGUIイベントでエラーメッセージの表示を行なっているので、ヒエラルキービューの再描画処理が走る都度新しくエラーが出力されます。 これがかなりの頻度なので、ヒエラルキービューを操作しているとすぐにこんな状態になってしまいます。 もう少し控えめでも良いのですが、これだけ煩かったらすぐに解消したくなるからまあいいかな、と自分を納得させています。 コード全文 Missingチェックを行うEditor拡張 #nullable enable using System.Linq; using UnityEditor; using UnityEngine; /// <summary> /// リンク切れ情報を表示する拡張機能 /// </summary> /// <remarks> /// <para>Unity2020.3.5f1で動作確認。</para> /// <para> /// <list type="bullet"> /// <item><description>コンポーネントがMissingとなっている場合は!のアイコンを表示し、エラーログも表示。</description></item> /// <item><description> /// コンポーネント内の参照項目にMissingとなっているものが存在する場合は!のアイコンを表示し、エラーログも表示。 ///(ログはコンポーネント単位で最初に見つかったもののみ表示) /// </description></item> /// </list> /// </para> /// </remarks> public static class MissingReferenceChecker { private const int IconSize = 16; private const string WarningIconName = "console.warnicon"; private const string PropertyNameOfFieldId = "m_FileID"; private static Texture? warningIcon; [InitializeOnLoadMethod] private static void Initialize() { Enable(); /* * ビルトインアイコンの呼び出し方は以下を参考にした * https://qiita.com/Rijicho_nl/items/88e71b5c5930fc7a2af1 * https://unitylist.com/p/5c3/Unity-editor-icons */ #pragma warning disable UNT0023 // Coalescing assignment on Unity objects warningIcon ??= EditorGUIUtility.IconContent(WarningIconName).image; #pragma warning restore UNT0023 // Coalescing assignment on Unity objects } private static void Enable() { EditorApplication.hierarchyWindowItemOnGUI -= CheckMissingReference; EditorApplication.hierarchyWindowItemOnGUI += CheckMissingReference; } private static void CheckMissingReference(int instanceID, Rect selectionRect) { // instanceIDをオブジェクト参照に変換 if (!(EditorUtility.InstanceIDToObject(instanceID) is GameObject gameObject)) return; var pos = selectionRect; pos.x = pos.xMax - IconSize; pos.width = IconSize; pos.height = IconSize; // オブジェクトが所持しているコンポーネント一覧を取得 var components = gameObject.GetComponents<Component>().ToList(); // Missingなコンポーネントが存在する場合はWarningアイコン表示 var existsMissing = components.RemoveAll(x => x == null) > 0; if (existsMissing) { UnityEngine.Debug.LogError(gameObject.name + "のコンポーネントにMissingのものが存在します。"); DrawIcon(pos, warningIcon!); } else { foreach (var component in components) { // SerializeFieldsにMissingなものが存在する場合はWarningアイコン表示 var existsMissingField = ExistsMissingField(component); if (existsMissingField) { DrawIcon(pos, warningIcon!); } } } } /// <summary> /// コンポーネントの設定値にMissingなものが存在するかどうかを確認する /// </summary> /// <param name="component">確認対象のコンポーネント</param> /// <returns>MissingなSerializedFieldが存在するかどうか</returns> /// <remarks> /// 以下の条件を満たす場合はMissingと見なす。Unityのバージョンが変わると変更になる可能性有。 /// <list type="bullet"> /// <item><description><see cref="SerializedProperty.propertyType"/>が<see cref="SerializedPropertyType.ObjectReference"/></description></item> /// <item><description><see cref="SerializedProperty.objectReferenceInstanceIDValue"/>がnull</description></item> /// <item><description>fileIDが0ではない</description></item> /// </list> /// </remarks> private static bool ExistsMissingField(Component component) { var ret = false; var serializedProp = new SerializedObject(component).GetIterator(); while (!ret && serializedProp.NextVisible(true)) { if (serializedProp.propertyType != SerializedPropertyType.ObjectReference) continue; if (serializedProp.objectReferenceValue != null) continue; var fileId = serializedProp.FindPropertyRelative(PropertyNameOfFieldId); if (fileId == null || fileId.intValue == 0) continue; UnityEngine.Debug.LogError( component.name + "の" + component.GetType().Name + "のフィールド" + serializedProp.propertyPath + "がMissingとなっています。"); ret = true; } return ret; } private static void DrawIcon(Rect pos, Texture image) { GUI.DrawTexture(pos, image, ScaleMode.ScaleToFit); } } コンポーネントアイコン表示機能と併用 こちらに記載した、ヒエラルキーウィンドウにコンポーネントのアイコンを表示するEditor拡張と合わせると、こんな風になります。 コンポーネントアイコン表示機能と併用 #nullable enable using System.Linq; using UnityEditor; using UnityEngine; /// <summary> /// Hierarchyウィンドウにコンポーネントのアイコンを表示する拡張機能 /// </summary> /// <remarks> /// <para>Unity2020.3.5f1で動作確認。</para> /// <para> /// <list type="bullet"> /// <item><description>Transform以外のコンポーネントのアイコン表示。</description></item> /// <item><description>スクリプトのアイコンは複数付与されていても1つのみ表示。</description></item> /// <item><description>コンポーネントが無効になっている場合はアイコン色が半透明になっている。</description></item> /// <item><description>コンポーネントがMissingとなっている場合は!のアイコンを表示し、エラーログも表示。</description></item> /// <item><description> /// コンポーネント内の参照項目にMissingとなっているものが存在する場合は!のアイコンを表示し、エラーログも表示。 ///(ログはコンポーネント単位で最初に見つかったもののみ表示) /// </description></item> /// <item><description>ヒエラルキーウィンドウで右クリックで表示されるメニュー「コンポーネントアイコン表示切替」の選択で表示/非表示の切替可能。</description></item> /// </list> /// </para> /// </remarks> public static class ComponentIconDrawerInHierarchy { private const int IconSize = 16; private const string MenuPath = "GameObject/コンポーネントアイコン表示切替"; private const string ScriptIconName = "cs Script Icon"; private const string WarningIconName = "console.warnicon"; private const string PropertyNameOfFieldId = "m_FileID"; private static readonly Color colorWhenDisabled = new Color(1.0f, 1.0f, 1.0f, 0.5f); private static Texture? scriptIcon; private static Texture? warningIcon; private static bool enabled = true; [InitializeOnLoadMethod] private static void Initialize() { UpdateEnabled(); /* * ビルトインアイコンの呼び出し方は以下を参考にした * https://qiita.com/Rijicho_nl/items/88e71b5c5930fc7a2af1 * https://unitylist.com/p/5c3/Unity-editor-icons */ #pragma warning disable UNT0023 // Coalescing assignment on Unity objects scriptIcon ??= EditorGUIUtility.IconContent(ScriptIconName).image; warningIcon ??= EditorGUIUtility.IconContent(WarningIconName).image; #pragma warning restore UNT0023 // Coalescing assignment on Unity objects } [MenuItem(MenuPath, false, 20)] private static void ToggleEnabled() { enabled = !enabled; UpdateEnabled(); } private static void UpdateEnabled() { EditorApplication.hierarchyWindowItemOnGUI -= DisplayIcons; if (enabled) EditorApplication.hierarchyWindowItemOnGUI += DisplayIcons; } private static void DisplayIcons(int instanceID, Rect selectionRect) { // instanceIDをオブジェクト参照に変換 if (!(EditorUtility.InstanceIDToObject(instanceID) is GameObject gameObject)) return; var pos = selectionRect; pos.x = pos.xMax - IconSize; pos.width = IconSize; pos.height = IconSize; // オブジェクトが所持しているコンポーネント一覧を取得 var components = gameObject .GetComponents<Component>() .Where(x => !(x is Transform || x is ParticleSystemRenderer)) .Reverse() .ToList(); // Missingなコンポーネントが存在する場合はWarningアイコン表示 var existsMissing = components.RemoveAll(x => x == null) > 0; if (existsMissing) { UnityEngine.Debug.LogError(gameObject.name + "のコンポーネントにMissingのものが存在します。"); DrawIcon(ref pos, warningIcon!); } var existsScriptIcon = false; foreach (var component in components) { // SerializeFieldsにMissingなものが存在する場合はWarningアイコン表示 var existsMissingField = ExistsMissingField(component); if (existsMissingField) DrawIcon(ref pos, warningIcon!); Texture image = AssetPreview.GetMiniThumbnail(component); if (image == null) continue; // Scriptのアイコンは1つのみ表示 if (image == scriptIcon) { if (existsScriptIcon) continue; existsScriptIcon = true; } // アイコン描画 DrawIcon(ref pos, image, component.IsEnabled() ? Color.white : colorWhenDisabled); } } /// <summary> /// コンポーネントの設定値にMissingなものが存在するかどうかを確認する /// </summary> /// <param name="component">確認対象のコンポーネント</param> /// <returns>MissingなSerializedFieldが存在するかどうか</returns> /// <remarks> /// 以下の条件を満たす場合はMissingと見なす。Unityのバージョンが変わると変更になる可能性有。 /// <list type="bullet"> /// <item><description><see cref="SerializedProperty.propertyType"/>が<see cref="SerializedPropertyType.ObjectReference"/></description></item> /// <item><description><see cref="SerializedProperty.objectReferenceInstanceIDValue"/>がnull</description></item> /// <item><description>fileIDが0ではない</description></item> /// </list> /// </remarks> private static bool ExistsMissingField(Component component) { var ret = false; var serializedProp = new SerializedObject(component).GetIterator(); while (!ret && serializedProp.NextVisible(true)) { if (serializedProp.propertyType != SerializedPropertyType.ObjectReference) continue; if (serializedProp.objectReferenceValue != null) continue; var fileId = serializedProp.FindPropertyRelative(PropertyNameOfFieldId); if (fileId == null || fileId.intValue == 0) continue; UnityEngine.Debug.LogError( component.name + "の" + component.GetType().Name + "のフィールド" + serializedProp.propertyPath + "がMissingとなっています。"); ret = true; } return ret; } private static void DrawIcon(ref Rect pos, Texture image, Color? color = null) { Color? defaultColor = null; if (color.HasValue) { defaultColor = GUI.color; GUI.color = color.Value; } GUI.DrawTexture(pos, image, ScaleMode.ScaleToFit); pos.x -= pos.width; if (defaultColor.HasValue) GUI.color = defaultColor.Value; } /// <summary> /// コンポーネントが有効かどうかを確認する拡張メソッド /// </summary> /// <param name="this">拡張対象</param> /// <returns>コンポーネントが有効となっているかどうか</returns> private static bool IsEnabled(this Component @this) { var property = @this.GetType().GetProperty( "enabled", typeof(bool)); return (bool)(property?.GetValue(@this, null) ?? true); } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSIoTをC#から操作する方法(Windowsアプリ)

はじめに AWSIoT は便利。 マイコンやラズパイからクラウドにセンサーデータを送信したり、 AWSのサイトからモーターを制御する、ということがお手軽に出来る。 技術記事も充実しており、マイコンやラズパイからAWSIoTのモノ(クラウド)と通信して何かを実現する記事は溢れている。 Raspberry pi + AWSで温度をスマホに出力させる Raspberry PiとAWS IoTでLチカしてみた RaspberryPiとAWS IoT CoreでMQTT通信をしてみた 一方、スマホやPCからAWSIoTに接続してみた、という記事は少ない。 (AWSIoTを使いたい層のメインが組み込みだから?) しかし、センサーデータはアプリやWEBで見られる必要があるし、 モーターは(遠隔の)PCから操作できなければならない。 マイコン側だけでは片手落ちで、クライアント側アプリも一緒に開発する必要がある。 AWSIoTを使ったIoTシステムの例を構成図にした。 この図の右側を開発したい。 sundarnarasimanさんが作成されたC#+AWSIoTのサンプルがあったため、これをベースに作っていく。 目次 やりたいこと C#のデスクトップアプリからAWSIoTに対してMQTT通信(送受信)を行う。 環境 Windows10 VisualStudio2019 作成済のAWSアカウント 手順 モノづくり お決まりの日本伝統モノづくり。 最近、UIが変わったみたいだが気にしない。 ① AWSの準備 下記の記事の「AWSの準備」章に従ってAWSIoTでモノを作成する。 Raspberry PiでAWS IoT Coreと接続し、GPIO制御をしてみた 注意点 ポリシーの設定(下記)を忘れないこと! ここで許可されていないと通信できない。 証明書とキー(下記)をすべてダウンロードする。ダウンロードしたファイルは1つのフォルダにまとめて保存する。 ② PKCS12にする .NetAPIでは.pemファイルは扱うことができないため、.pfx形式に変更する必要がある。コマンドプロンプトからOpenSSLを使用して変換する。 コマンドは下記 (.pem .key .crtファイルはダウンロードしたファイル名、.pfxは任意のファイル名) aws.bat openssl pkcs12 -export -in certificate.cert.pem -inkey certificate.private.key -out certificate.cert.pfx -certfile AmazonRootCA1.crt パスワードを入力する必要があるが、後で使うのでメモしておく。 sundarnarasimanさんが作成されたサンプルではより詳しく解説している。 WindowsだとデフォルトでOpenSSLコマンドが使えないため、記事を参考にインストールする。 アプリケーションの作成 ① デスクトップアプリケーションの作成 Visual Studio2019を起動して「Windowsフォールアプリケーション(.Net Framework) 」を選択し、プロジェクトを作成する。 ② MQTTパッケージの追加 Visual Studio > プロジェクト名を右クリック > Nugetパッケージの管理 から M2mqtt をインストール ③ソースコードを作成する AwsComm.cs internal class AwsComm : IAwsiot { public string endpoint => "xxxxx.amazonaws.com"; public string topic => "xxxx"; public string caname => "xxx.crt"; public string pfxname => "xxx.pfx"; public string pfxpassword => "xxxxxx"; private MqttClient client; public void Connect() { var caCert = X509Certificate.CreateFromCertFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, caname)); var clientCert = new X509Certificate2(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pfxname), pfxpassword); this.client = new MqttClient(endpoint, 8883, true, caCert, clientCert, MqttSslProtocols.TLSv1_2); this.client.MqttMsgPublishReceived += PublishReceived; string clientId = Guid.NewGuid().ToString(); this.client?.Connect(clientId); this.client.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE }); } public void Disconnect() { this.client?.Disconnect(); } public void Publish(string message) { this.client.Publish(topic, Encoding.UTF8.GetBytes($"{message}")); } public void PublishReceived(object sender, MqttMsgPublishEventArgs e) { var awsdata = new AwsData(e); awsdata.DataChangeFlag = true; } } ソースコード全文は以下 https://github.com/ikenohotori/AWSIoTSample 下記は自分で作成した値を入力する。 endpoint => "xxxxx.amazonaws.com"; public string topic => "xxxx"; public string caname => "xxx.crt"; public string pfxname => "xxx.pfx"; public string pfxpassword => "xxxxxx"; endpoint→ AWS IoTコンソール > 設定 で確認する。 topic→ 好きな値で問題ない。※AWSコンソールで確認する時に使用する。 caname、pfxname、pfxpassword→ 作成した各ファイル・パスワード名。ファイルを格納した場所にパスを合わせる。 動作確認 AWSコンソール>テスト>MQTTテストクライアント を使ってアプリの動作を確認する。 前半:アプリからawsトピックに「test!!」を送信 後半:AWSコンソールからawsトピックに「OK!!」を送信 最後に 送受信はすごく簡単に出来た!! 課題としては、受信処理が100msごとにクラウド上のトピックに対して確認を行っているため、アプリの処理が重くなる&送受信の間で遅延(約200ms)が発生している。デバイスシャドウを利用して、トピック更新後に即アプリに通知される仕組みを実装していきたい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# 複数のクラスに同一のインスタンスを提供する方法

概要 通信するクラスや外部リソースを操作するクラスの場合、複数のクラスから操作するときに同一のインスタンスを取得する方が都合がいいことがあります。 その際の実装の例を記載しておきます。 コード public class UniqueClass { /// <summary> /// 共通のUniqueClassのインスタンス /// </summary> private static UniqueClass _instance = null; /// <summary> /// インスタンスを取得 /// </summary> /// <returns></returns> public static UniqueClass GetInstance() { if (_instance == null) { _instance = new UniqueClass(); } return _instance; } /// <summary> /// プライベートコンストラクタ /// </summary> private UniqueClass() { } } 解説 上記UniqueClassのポイントは以下の3点です。 staticな自分自身のインスタンス 外部にインスタンスを与えるGetInstance()メソッド プライベートコンストラクタ 1つずつ解説していきます。 1.staticな自分自身のインスタンス これは複数のクラスに渡すためのユニークなインスタンスとなります。 2.外部にインスタンスを与えるGetInstance()メソッド 外部クラスからインスタンスを取得するための関数です。 1のインスタンスをリターンします。 ※外部から呼び出す際は、 UniqueClass unique = UniqueClass.GetInstance(); のようにしてインスタンスを取得します。 3.プライベートコンストラクタ privateで宣言されたコンストラクタです。 この宣言をすると外部からnewを使ったインスタンスを生成できなくなります。 間違ってnewを使用されたくないときに宣言してください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[C#]MVVMの実装方法

はじめての投稿です 概要 C# のMVVMの実装方法について忘れてしまった。 初歩的なところから再勉強したメモ 結果 これが一番わかりやすかった 世界で一番短いサンプルで覚えるMVVM入門 | 趣味や仕事に役立つ初心者DIYプログラミング入門 詳細 詳細というか、補足説明みたいな感じで、 上記記事の内容をUML図でみたいので作成してみた。 余談1 いつも、インスタンスってどうやって表すのだろうと調べるけど中々説明している記事にたどり着かない。 集約とかコンポジションで表すそうな。下記参考サイト参照。 余談2 plantumlでのスコープって□とかで表示されるけど、結局わかりづらい。 わざわざprivate とか追記してしまう。みんなわかるのかな。 参考にしたサイト 世界で一番短いサンプルで覚えるMVVM入門 | 趣味や仕事に役立つ初心者DIYプログラミング入門 【コードで分かるUMLシリーズ】クラス図の書きかた(集約とコンポジションの意味の違い) - Qiita
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む