メインコンテンツまでスキップ

DIコンテナの使い方

土井
ディアシステム(株)開発一部第2課

別記事にて依存関係逆転の原則と DI(Dependency Injection)の手法について記載いたしました。今回はこの手法を使うときに便利な DI コンテナの使い方を紹介します。

前提条件

以下のツールを事前にインストールしておいてください

  • Visual Studio また以下のライブラリを Nuget パッケージよりインストールしてください
  • Microsoft.Extensions.DependencyInjection
動作環境
  • Visual Studio Community 2022
  • .NET6.0

早速 DI コンテナを使ってみる

まず使用するインターフェースとクラスを用意します。

public interface ILogger
{
void Info(string message);
}

public class Logger : ILogger
{
public void Info(string message)
{
Console.WriteLine(message)
}
}

次に DI コンテナを作成します。
DI コンテナは「ServiceCollection」クラスを使用します。
この「ServiceCollection」クラスは DI の情報を格納するクラスで、ここにインターフェースとクラスを登録していきます。
※TestFuncClass はこの後、作成します。

using Microsoft.Extensions.DependencyInjection;

・・・
public class Program
{

static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddSingleton<ILogger, Logger>();

TestFuncClass inst = new TestFuncClass();
inst.Execute(services);
}
}

インターフェースとクラスの登録には3種類のメソッドが用意されており、
状況によって使い分けます。各メソッドの使い方等については後述にて記載いたします。

  • AddSingleton アプリケーション全体で一度だけインスタンスが生成され、全てのリクエストで同じインスタンスが再利用されます。

  • AddScoped 各スコープごとに新しいインスタンスが生成されます。

  • AddTransient 各リクエストごとに新しいインスタンスが生成されます。

次にこの DI コンテナを使ったクラスを作成します。
BuildServiceProvider()メソッドは ServiceCollection に登録されたサービスのインスタンスを解決し、提供する役割を持ちます。
Execute メソッド内では BuildServiceProvider()から GetService メソッドを使って、ILogger を継承した Logger のインスタンスを受け取ります。これで TestFuncClass は ILogger を継承した Logger クラスのメソッドを使用することができます。

public class TestFuncClass
{
public void Execute(ServiceCollection services)
{
var serviceProvider = services.BuildServiceProvider();
var logger = serviceProvider.GetService<ILogger>();
logger.Info(“test”);
}
}

また Logger 内に string 型の引数を持つコンストラクタがある場合、インスタンスとインターフェースの登録は以下のようになります。

public class Logger : ILogger
{
private string _subMessage;
public Logger_Part2(string message)
{
_subMessage = message;
}
public void Info(string message)
{
Console.WriteLine(message + _subMessage);
}
}

public class Program
{
static void Main(string[] args)
{
TestFuncClass inst = new TestFuncClass();
var services = new ServiceCollection();

services.AddSingleton<ILogger>(provider => new Logger(“追加メッセージ”));
inst.Execute(services);
}
  }

DI コンテナへの登録の3種類の確認
前述にて DI コンテナへ登録する際に 3 つのメソッドがあることを記載しました。
ここではその使い方や動作の違いを確認していきたいと思います。

ILogger と Logger クラスを以下のように修正します。

public interface ILogger
{
stirng SubMessage{ get; set;}
void Info(string message);
}

public class Logger : ILogger
{
public string SubMessage { get; set; }
public void Info(string message)
{
Console.WriteLine(message)
}
}
  • AddSingleton
    アプリケーション全体で一度だけインスタンスが生成されるので、インスタンスの受け取りを再度行っても、同じインスタンスが取得され logger.SubMessage に入れた値がそのままコンソールへ表示されています。
public class Program
{
Static void Main(string[] args)
{
var services = new ServiceCollection();
// DIコンテナへの登録
services.AddSingleton<ILogger,Logger>();

var serviceProvider = services.BuildServiceProvider();
// インスタンス受け取り
var logger = serviceProvider.GetService<ILogger>();
logger.SubMessage = “追加メッセージ”;
logger.Info(“test ++ logger.SubMessage);
// もう一度インスタンスを受け取る
logger = serviceProvider.GetService<ILogger>();
logger.Info(“test ++ logger.SubMessage);
}
}

出力結果

test +追加メッセージ
test +追加メッセージ
  • AddScoped
    AddScoped では各スコープごとに新しいインスタンスが生成されます。
    使い方としては CreateScope()メソッドによって、スコープを作成し、Dispose()メソッドを使うことで、スコープを破棄します。
    このスコープを破棄しない限りは GetService()メソッドを実行しても、同じインスタンスが返されます。 スコープを再作成すると、新しいインスタンスが生成されます。
public class Program
{
Static void Main(string[] args)
{
var services = new ServiceCollection();
// DIコンテナへの登録
services. AddScoped<ILogger,Logger>();
var serviceProvider = services.BuildServiceProvider();
// スコープの作成
var scope = serviceProvider.CreateScope();
        // インスタンス受け取り
var logger = scope.ServiceProvider.GetService<ILogger>();
logger.SubMessage = “追加メッセージ”;
logger.Info(“test ++ logger.SubMessage);
// もう一度インスタンスを受け取る
logger = scope.ServiceProvider.GetService<ILogger>();
logger.Info(“test ++ logger.SubMessage);
// スコープの破棄
Scope.Dispose();

// スコープの再作成
scope = serviceProvider.CreateScope();
logger = scope.ServiceProvider.GetService<ILogger>();
logger.Info(“test ++ logger.SubMessage);
// スコープの破棄
Scope.Dispose();
}
}

出力結果

test +追加メッセージ
test +追加メッセージ
test +
  • AddTransient
    リクエストのたびに新しいインスタンスが生成されるため、GetService()の実行のたびに新しいインスタンスが生成されます。そのため2つ目の出力の際、logger.SubMessage に入れた値は空の状態となっています。
public class Program
{
Static void Main(string[] args)
{
var services = new ServiceCollection();
// DIコンテナへの登録
services. AddTransient<ILogger,Logger>();
var serviceProvider = services.BuildServiceProvider();
// インスタンス受け取り
var logger = serviceProvider.GetService<ILogger>();
logger.SubMessage = “追加メッセージ”;
logger.Info(“test ++ logger.SubMessage);
// もう一度インスタンスを受け取る
logger = serviceProvider.GetService<ILogger>();
logger.Info(“test ++ logger.SubMessage);
}
}

出力結果

test +追加メッセージ
test +

以上が DI コンテナ(Microsoft.Extensions.DependencyInjection)の使い方です。
今後もこの機能を使って、依存関係逆転の原則に沿った実装を行っていきたいと思います。

依存関係逆転の原則とDI(Dependency Injection)

土井
ディアシステム(株)開発一部第2課

業務の中で「依存関係逆転の原則」という原則とそれに関わるデザインパターンの「DI(Dependency Injection)」について、学ぶ機会があったので、ここに書き記します。

動作環境 C#

依存関係逆転の原則とは?

ソフトウェア設計においての概念です。
この原則には以下二つのルールがあります。

  • 高レベルのモジュールは低レベルのモジュールに依存してはならない。両者は抽象に依存すべきである
  • 抽象は詳細に依存してはならない。詳細は抽象に依存すべきである。

ここで言う、抽象は「インターフェース」、詳細は「具体的な実装」のことだと思ってください。
つまり、他クラスのメソッド等を使いたいときはそのクラスに依存するようなコードでは無く、インターフェースに依存するようなコードにしましょうということです。
そのようなプログラムを作りたいときに使われるのが、DI(Dependency Injection)です。

DIとは?

デザインパターンの一つです。プログラムの必要な部分を外部から入れてあげるような手法です。この手法を使用することによりテストが簡単になったり、コードを再利用しやすくなります。またコードの柔軟性も向上します

この二つをふわっと理解しながら、実際にプログラムで考えてみましょう。
例えばロボット作りで考えてみます。
ロボットには燃料が必要ですよね。その燃料を入れる部分をDIを使わずに作ると以下のようになります。

    public class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
Electricity electricity = new Electricity();
// ロボットに電気を渡す
robot.Start(electricity);
}
}

public class Robot
{

public void Start(Electricity electricity)
{
electricity = new Electricity();
// ロボットに燃料を注入する
electricity.SupplyElectricityPower();
}
}

public class Electricity
{
public void SupplyElectricityPower()
{
Console.WriteLine("電気を注入します");
}
}

この例では、ロボットの燃料には電気(Electricity)が使われています。
メイン部分でRobotクラスにインスタンス化したElectricityクラスを渡しています。またRobotクラスではElectricityクラスのSupplyElectricityPowerメソッドを使っています。
この状態だとRobotクラスはElectricityクラスを必ず使わないと動かないため、RobotクラスはElectricityクラスに依存している状態となっています。

次に今回のテーマであるDI(Dependency Injection)の手法を使うと次のようになります。

        public class Program
{
static void Main(string[] args)
{
IEnergy electricity = new Electricity();
// ロボットに電気を渡す
Robot robot = new Robot(electricity);
robot.Start();
}
}

public class Robot
{
private IEnergy _energy;
public Robot(IEnergy energy)
{
_energy = energy;
}
public void Start()
{
// ロボットに燃料を注入する
_energy.SupplyPower();
}
}
// 新しくインターフェースを作成
public interface IEnergy
{
public void SupplyPower();
}

// インタフェースを継承してクラスを作成
public class Electricity : IEnergy
{
public void SupplyPower()
{
Console.WriteLine("電気を注入します");
}
}

IEnergyというインターフェースを作成し、Electricityクラスはそれを継承したものとなっています。またRobotクラスはIEnergyインターフェースを継承したクラスを入れることで動作するようになっています。
このようにするとRobotクラスはElectricityクラスに依存することなく、動作させることができます。

何が良いのか?

  • コードの再利用性
    例えば、ロボットの燃料が電気ではなく、ガソリンに変わったとしましょう。
    その場合、IEnergyを継承した新しくガソリンを取り扱うクラスを用意し、その中にガソリンを注入するメソッドを用意することになります。
    public class Gasoline : IEnergy
{
public void SupplyPower()
{
Console.WriteLine("ガソリンを注入します");
}
}

DIを使っているとRobotクラスはの中身は変えずにGasolineクラスを使うことができます。

    public class Program
{
static void Main(string[] args)
{
// 電機ではなくガソリンに変更
//IEnergy electricity = new Electricity();
IEnergy gasoline = new Gasoline();

// ロボットにガソリンを渡す
Robot robot = new Robot(gasoline);
robot.Start();
}
}

// Robotクラスの中身は変えなくていい
public class Robot
{
private IEnergy _energy;
public Robot(IEnergy energy)
{
_energy = energy;
}
public void Start()
{
// ロボットに燃料を注入する
_energy.SupplyPower();
}
}
  • テストのしやすさ
    Robotクラスのテストをする際に、Gasolineクラスを必ず用意しなくても、Energyインターフェースを経由したテスト用のクラスを作成しテストが行えます。

実際にあるような状況で考えてみましょう。
例えば、500人分の従業員の給料を計算し、明細にして印刷するようなプログラムがあるとします。
必要なクラスは「従業員のデータを取得するクラス」、データをもとに「計算するクラス」、給料明細を「印刷するクラス」の3つです。この一連の動作のテストをする際に、 「印刷するクラス」に依存している状態だと、テストをするたびに給料明細を印刷することになってしまい、紙を大量に使用し、社内は深刻な紙不足に陥ります。そんなときにDIの手法を使った実装にしていれば、テスト用の出力クラスを作ることができ、印刷ではなく、PDFをローカルのフォルダに出力することで印刷したことにしてしまえば、テスト時に印刷をする必要は無くなります。(もちろん、本番に移行するときは一度印刷して確かめてくださいね。)

画像1

  • コードの柔軟性
    DIの手法を使ったプログラムの場合、インターフェースに依存している状態になるので、それを継承したプログラムであれば中身がどう変わっても、使う側に変更の必要がなく、将来的な変更や拡張がしやすくなります。
public class Program
{
static void Main(string[] args)
{
IEnergy gasoline = new Gasoline();

// ロボットにガソリンを渡す
Robot robot = new Robot(gasoline);
robot.Start();
}
}


public class Robot
{
private IEnergy _energy;
public Robot(IEnergy energy)
{
_energy = energy;
}
public void Start()
{
// SupplyPowerの処理の中身は変わっているが変更する必要がない
_energy.SupplyPower();
}
}
public class Gasoline : IEnergy
{
// 処理を変更
public void SupplyPower()
{
Console.WriteLine(“必要な燃料の量を計算します”)
Console.WriteLine("ガソリンを注入します");
  Console.WriteLine(“注入完了をお知らせします);
}
}

以上が依存関係逆転の原則とDIについてとなります。
具体的な実装に依存するのではなく、インターフェースに依存したつくりを行って、管理、テストしやすいプログラムの実装を目指していきたいと思います。

次は別記事にて、DIの手法を使う際に便利なDIコンテナというツールの使い方について紹介します。

情報セキュリティマネジメント試験(SG)合格体験記

酒井
ディアシステム(株)開発二部第1課兼管理部

こんにちは。開発二部第1課兼管理部の酒井です。
昨年の8月、無事に情報セキュリティマネジメント試験(SG)に合格することができましたので、 簡単ではありますが合格までの道のりや感想などを綴らせていただきます。

まず、情報セキュリティマネジメント試験(SG)について簡単に説明させていただきます。

資格の位置づけ

情報セキュリティマネジメントの計画・運用・評価・改善を通して組織の情報セキュリティ確保に貢献し、脅威から継続的に組織を守るための基本的なスキルを認定する試験です。
〈共通キャリア・スキルフレームワーク(CCSF)レベル2相当〉
※基本情報技術者試験と同レベル

試験内容

試験時間: 120分
問題数: 60問(科目A:多肢選択式(四肢択一)、科目B:多肢選択式)
合格点: 1000点満点中600点以上
出題分野:
●科目Aの出題内容

  • 情報セキュリティ全般
  • 情報セキュリティ管理
  • 情報セキュリティ対策
  • 情報セキュリティ関連法規
  • テクノロジ
  • マネジメント
  • ストラテジ

●科目Bの出題内容

業務の現場における情報セキュリティ管理の具体的な取組みである情報資産管理、リスクアセスメント、IT利用における情報セキュリティ確保、委託先管理、情報セキュリティ教育・訓練などのケーススタディによる出題を通して、情報セキュリティ管理の実践力を問う。

受験の動機

私が本資格を受験しようと思った動機は

  • 社内でISMSの管理者や情シス的な役割をしておりセキュリティに常に関わっているため、より一層の知識を身に付ける必要性があると感じたこと
  • 今まで学んできた自分の知識や経験を客観的に証明したいと思ったこと
    あとは、長年IT業界にはいますが今まであまり資格取得には挑戦していなかったためキャリアアップや自信をつけるために資格を取得したいという気持ちで受験することを決心しました。

勉強法

まずは、教材として書籍を購入し通勤時間などを使用して一通り書籍を読むことに集中しました。私が使用したのは「情報セキュリティマネジメント 合格教本」です。
文字ばかりの書籍は個人的に苦手なのでこの書籍は図解などが多様されていて読みやすい、問題集なども含まれており実践的な対策ができました。
その後は無料の過去問サイトを利用して、とにかく繰り返し過去問に挑戦し問題形式に慣れること、時間配分や解答の仕方を実践的に練習しました。

試験当日の流れ

私は自宅から近い試験会場で設置されたコンピュータを使用して実施するCBT方式で受験しました。
試験当日は緊張しましたが、60問で120分のため1問1問慎重に解答していっても試験時間の全ての時間を使い切らないくらいの時間で終えることができたので時間については割と余裕を持てるかと思います。
ただ、自信をもって回答できた問題と不安な問題、体感では五分五分くらいでした。
テスト全問解答直後に画面で結果を確認できるので、最後の結果確認のボタンを押す際は緊張しましたが結果は無事に合格でした。
点数は思ったよりは取れておらず、合格に対して余裕の点数とはいえませんでしたが…。

最後に

個人的にはISMSの資格取得から関わり維持を通じ学んできたこと、その他今まで日々の業務で積み重ねてきた知識や経験のおかげで全体の4割くらいは勉強前から既に理解できていたことは勉強を進める中で合格への自信になりました。
また、本資格は昔と違ってほぼ毎日のように受験ができるため、年に二度しかチャンスがないというようなプレッシャーが少ないこと、受験日や勉強のスケジュール調整などもしやすいため日々の仕事をしながらでも挑戦しやすい資格だと思います。
あとは、最新の時事問題などからも出題されることがあるため、書籍から得られる知識だけでなく試験前にネットなどで最新のセキュリティ知識や話題を事前に確認しておくことをオススメします。
情報セキュリティマネジメント試験の合格は勉強を通じてさらなる知識を得ることができたこと、また、自信にもなりこれからまた別の資格にも挑戦していきたいと思いました。

初級者向け!ユニットテストを使ってカバレッジを計測、テストの品質を向上させよう

鶴田
ディアシステム(株)開発一部第2課

今回の記事では、ユニットテストを使ってカバレッジを計測し、さらに向上させる方法を解説します。

ユニットテストとは、プログラムの一部分を独立してテストする手法で、主に早期のバグ発見が目的です。 ユニットテストを導入すると、テストが十分に行き届いているかを確認できるようになり、テスト品質の 向上にも大いに役立ちます。さらに、リファクタリングや仕様変更の際に安心してコードを修正できるようになり、 開発効率の向上にも貢献するなど、開発全体において非常に重要な役割を果たします。

カバレッジとは、テスト対象のプログラムのどの部分が実際にテストされているかを示す指標です。 カバレッジを計測することで、テストが漏れている部分が明確になり、より高品質なテストへと つなげられます。

私自身、「ユニットテストでカバレッジを計測して品質を上げる」方法は、経験の浅いプログラマーにも わかりやすく効果的だと考えています。高品質な成果物はチーム全体の意識を高めるだけでなく、 モチベーションの向上にもつながります。 経験が浅い方でも、ユニットテストを活用すればチームに十分貢献できるでしょう。

「何から手を付ければいいかわからない」という方こそ、ぜひ参考にしてみてください。

動作環境

  • 開発環境: Visual Studio 2022 Community
  • 言語: C#

今回作成するプログラムの仕様

  • 製品クラス
    品番ごとに製品の名前と価格、廃番日付を保持する

  • 在庫クラス
    品番ごとに在庫数を保持する

  • 上記2クラスのユニットテストクラス

作成手順

  1. プロジェクトを2つ追加する

    • 1つ目のプロジェクト

      • プロジェクトの種類: クラスライブラリ
      • プロジェクトの名前: ClassLibrary1
    • 2つ目のプロジェクト

      • プロジェクトの種類: MSTestテストプロジェクト
      • プロジェクトの名前: TestProject1

    もともとある Class1.cs は削除してください。

  2. ClassLibrary1 に製品クラスと在庫クラスを追加する

製品マスタは「品番、製品名、価格、廃番日付」のプロパティを、在庫マスタは「品番、在庫数」のプロパティを持つようにします。下記のコードを追加してください。

製品クラス(Product)と在庫クラス(Zaiko)

public class Product
{
/// <summary>
/// 製品CD
/// </summary>
public string ProductCode { get; }

/// <summary>
/// 製品名称
/// </summary>
public string Name { get; }

/// <summary>
/// 価格
/// </summary>
public decimal Price { get; }

/// <summary>
/// 廃番日付
/// </summary>
public string? HaibanDate { get; }

public Product(string productCode, string name, decimal price)
{
if (string.IsNullOrWhiteSpace(productCode)) throw new ArgumentException("製品CDは必須です");
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("名称は必須です");
if (price < 0) throw new ArgumentException("製品価格は必須です");
if (haibanDate != null)
{
if (!DateTime.TryParseExact(haibanDate, "yyyyMMdd", null, System.Globalization.DateTimeStyles.None, out _))
throw new ArgumentException("廃番日付が有効な日付ではない");
}

ProductCode = productCode;
Name = name;
Price = price;
HaibanDate = haibanDate;
}
}

public class Zaiko
{
public string ProductCode { get; }
public int ZaikoSu { get; private set; }

public Zaiko(string productCode, int zaikoSu)
{
if (string.IsNullOrWhiteSpace(productCode)) throw new ArgumentException("製品CDは必須");
if (zaikoSu < 0) throw new ArgumentException("在庫数はゼロ以上のみ有効");

ProductCode = productCode;
ZaikoSu = zaikoSu;
}

public void AddZaikoSu(int amount)
{
if (amount <= 0) throw new ArgumentException("追加在庫数はゼロ以上のみ有効");
ZaikoSu += amount;
}
}

  1. TestProject1 にテストコードを追加する
[TestClass]
public class ProductTests
{
[TestMethod]
[Priority(0001)] // テストの優先度
public void コンストラクタ01()
{
var target = new Product("001", "商品A", 100, "20250101");
Assert.AreEqual("001", target.ProductCode);
Assert.AreEqual("商品A", target.Name);
Assert.AreEqual(100, target.Price);
Assert.AreEqual(target.HaibanDate, "20250101");
}
}
  1. 在庫クラスのテストコードを追加する
[TestClass]
public class ZaikoTests
{
[TestMethod]
[Priority(0001)]
public void コンストラクタ()
{
var target = new Zaiko("001", 10);
Assert.AreEqual("001", target.ProductCode);
Assert.AreEqual(10, target.ZaikoSu);
}
}

Visual Studio でテストを実行すると、テストが実行され、テスト結果が表示されます。

テストエクスプローラー実行結果

これで完成・・・でしょうか?

それを確認するために、カバレッジを計測してみましょう。

VisualStudio 2022 へ Fine Code Coverage を導入する

  1. カバレッジを計測するために、以下のツールを使用します。

coverlet.console NuGet パッケージマネージャーより、coverlet.console をインストールします。

Fine Code Coverage https://marketplace.visualstudio.com/items?itemName=FortuneNgwenya.FineCodeCoverage

拡張機能より、Fine Code Coverage を検索してインストールしてください。

Visual Studio を再起動すると、ツールバーに Fine Code Coverage が表示されます。

拡張機能→Fine Code Coverage→設定 より色の設定を確認してください。以下の設定がおすすめです。

Fine Code Coverageおすすめ

Fine Code Coverage についての詳しい解説は、以下のサイトも参考になります。

カバレッジ100%へ

先ほどまで作成したソリューションを再度開いて、テストを実行します。

在庫クラスを確認してみましょう。

カバレッジ結果

オレンジや赤色の背景色がコード内に表示されています。 これは、赤はテストが実行されていない行(C0カバレッジ未達成)、オレンジは分岐の一部がテストされていない行(C1カバレッジ未達成)を示しています。

この行が「テストの漏れ」です。放置してはいけません。テストコードを追加します。

テストコードを以下の通り追加してください。

[TestClass]
public class ProductTests
{
[TestMethod]
[Priority(0001)] // テストの優先度を設定
public void コンストラクタ()
{
var target = new Product("001", "商品A", 100, "20250101");
Assert.AreEqual("001", target.ProductCode);
Assert.AreEqual("商品A", target.Name);
Assert.AreEqual(100, target.Price);
Assert.AreEqual(target.HaibanDate, "20250101");
}

[TestMethod]
[Priority(0002)]
public void コンストラクタ_Exception_ProductCode()
{
Assert.ThrowsException<ArgumentException>(() => new Product("", "商品A", 100));
}
/*
* 以下の通りにも記述可能です。
* ただ、カバレッジツールの制約上最後の } が未テスト行として認識されます。
*
[Priority(0002)]
[ExpectedException(typeof(ArgumentException))] // 例外が発生することを確認するテストコード
public void コンストラクタ_Exception_ProductCode()
{
var target = new Product("", "商品A", 100);
}
*/

[TestMethod]
[Priority(0003)]
public void コンストラクタ_Exception_Name()
{
Assert.ThrowsException<ArgumentException>(() => new Product("001", "", 100));
}

[TestMethod]
[Priority(0004)]
public void コンストラクタ_Exception_Price()
{
Assert.ThrowsException<ArgumentException>(() => new Product("001", "商品A", -1M));
}

[TestMethod]
[Priority(0005)]
public void コンストラクタ_Exception_HaibanDate()
{
Assert.ThrowsException<ArgumentException>(() => new Product("001", "商品A", 100, "100"));
}
}

public class ZaikoTests
{
[TestMethod]
[Priority(0001)]
public void コンストラクタ()
{
var target = new Zaiko("001", 10);
Assert.AreEqual("001", target.ProductCode);
Assert.AreEqual(10, target.ZaikoSu);
}

[TestMethod]
[Priority(0002)]
public void コンストラクタ_Exception_ProductCode()
{
Assert.ThrowsException<ArgumentException>(() => new Zaiko("", 10));
}

[TestMethod]
[Priority(0003)]
public void コンストラクタ_Exception_ZaikoSu()
{
Assert.ThrowsException<ArgumentException>(() => new Zaiko("001", -1));
}

[TestMethod]
[Priority(0101)]
public void AddZaikoSu_Exception()
{
var target = new Zaiko("001", 10);
Assert.ThrowsException<ArgumentException>(() => target.AddZaikoSu(-1));
}

[TestMethod]
[Priority(0102)]
public void AddZaikoSu()
{
var target = new Zaiko("001", 10);
target.AddZaikoSu(1);
Assert.AreEqual(11, target.ZaikoSu);
}
}

これですべての行がテストされました。 Fine Code Coverage で確認してみましょう。

表示→その他のウィンドウ→Fine Code Coverage を選択します。

カバレッジ結果

確かにカバレッジの欄には燦然と輝く100%の文字がっ!

これで、テストの漏れがなくなりました。

もちろん、カバレッジを100%にしたからといって、バグが完全になくなるわけではありません。しかし、ユニットテストを書く過程でコードを深く理解できるようになり、結果として品質向上につながります。

ぜひ、ユニットテストを書いてカバレッジを活用してみてください。そうすることで、チーム全体の品質意識が高まり、開発効率も向上するはずです。

ISO20022とは何ぞや?(外国送金編)

笹木
ディアシステム(株)開発一部第4課

開発1部第4課の笹木です。
これまで金融分野(銀行、信用金庫、損保会社系)を中心に様々なプロジェクトに携わらせて頂いておりますが、現在最も注目されているISO20022(外国送金)について触れてみたいと思います。

ISO20022とは?

ISO20022は金融通信メッセージの標準化を目指すために、ISOが定める国際規格を指します。
具体的には、これまで連携対象となった関連項目を固定長で定義し、「MT方式」で金融通信メッセージをSWIFT(※)を経由して世界各国間でやり取りしていましたが、これに代わって「XML形式」で金融通信メッセージのやり取りを行う形に変更されます。
(※)SWIFT:国際銀行間通信協会(Society for Worldwide Interbank Financial Telecommunicationの略でベルギーに本部を置く非営利組織です。)

画像1

現行システムの問題点は?

外国送金には仕向/被仕向送金があります。
世界各国毎にフォーマットが異なるため、送金のやり取りをする際にフォーマット変換が行われ、またフリーフォーマットでかつ古いため、名前、住所などの情報のチェックも機能せず、増加する送金情報への対応が複雑化し、業務効率化の妨げになっていました。

画像2

ISO20022の特徴およびメリット

可変長で柔軟に金融通信メッセージの送付が可能になることにより、各金融機関がコストを削減し、リスクにさらされる可能性を抑えながらトランザクションの効率化を向上させることが可能といわれており、以下のメリットが想定されます。

  • ビジネスプロセス通信用の共通言語が出来ます。
  • フォーマットが統一されることで大量の送金データを迅速・正確にシステム処理が可能となり、コンプライアンス対応の向上が見込まれます。
  • 他のプロトコルとの運用性が相互間で向上します。
     ➡ 海外送金だけではなく、国内取引(各金融機関 - 日銀間のやり取り等)についてもISO20022移行が行われています。
  • アルファベット以外の非ラテン文字(日本語ETC)についてもサポートが行われるようになります。
  • 送金に関する項目や文字数も拡充されます。
     ➡AML(アンチ・マネーロンダリング)の規制、反社会的勢力の強化や被仕向の入金送金失敗(口座不明等)などの減少が見込まれます。

画像3

最後に

先述の通り、外国送金について触れてみました。ISO20022についてデメリットがないかと言えば、それはNoであると考えます。少なからず、項目の構造化といった対処の検討も必要になると推測しますが、絶対やらないという選択肢はないと思いますので、デメリットは深く考えないようにした方がいいですね。最近のニュースでも円高/円安、金利など為替に関する様々な動きの背景や理由が語られています。為替相場を動かす要素は政治・経済や国際関係まで様々なのでこの辺の情報もしっかり注視しないといけませんね。

PowerBI 上のビジュアルよりエクスポートするファイル名をシステム日付にする方法

鶴田
ディアシステム(株)開発一部第2課

Power BI は、Microsoft 社が提供するビジネスインテリジェンス(BI)ツールです。 プログラムの経験がなくてもデータの加工が可能で、Microsoftの提供するローコードツールです。

AzureAD の MFA 認証と組み合わせることができたり、データの改ざんができず既存システムへの影響が低かったり、大量のデータを高速に処理できたりで利用が広がっています。 この記事では PowerBI 上のビジュアルよりエクスポートするファイル名を動的に変更する方法(今回はシステム日付)を書きます(わかっている人から見れば HelloWorld レベルなんですが汗)。

方法の概要

ビジュアルへメジャーを追加し、DAX 関数を使って動的なファイル名を作っておき、そのビジュアルのタイトルの条件付き書式より動的なファイル名を参照します。

詳しい方法

※当手順には PowerBI 添付のサンプルデータを使っています

1. ビジュアルへメジャーを追加し、DAX 関数を使って動的なファイル名を作っておきます。 ビジュアルを選択、メニュー→モデリング→新しいメジャー を選択、以下の通り入力します。

ファイル名 = FORMAT(NOW(), "yyyymmdd", "jp")

関数を入力

※もし固定文字列をつけたい時は「CONCATENATE 関数」などを組み合わせてください。

入力後、データに追加したメジャーが表示されます。

メジャーに追加された「ファイル名」

2. ビジュアルのタイトルの条件付き書式よりそのファイル名を参照します。

視覚化→ビジュアルの書式設定→全般→タイトルを選択します。 テキストの fx アイコンをクリック、基準にするフィールドへ「ファイル名」と入力します。

タイトル選択可能

うまくできるとビジュアルのタイトルにファイル名が表示されます。

ビジュアルのタイトルに表示されたファイル名

タイトルのファイル名を表示するのがイヤなら、文字の色を背景色と同じにすると見えなくなります。 ここまで出来たら、ビジュアルの右上「・・・」その他のオプションよりエクスポートを選択してみてください。 エクスポートされるファイル名に日付が設定されています。

作成したPBIファイルは ここ よりダウンロードできます。

以上です。

【まとめ】 PowerBI でなにかやりたい時は「対象となるビジュアルにメジャー追加して DAX 関数!」

【ボヤキ】 新しい製品が出るたびに同じような機能で違う名前がつくの、やめてほしいなー(・∀・;)

ローカル環境でAzure Storageをエミュレートする方法(Azurite使用)

土井
ディアシステム(株)開発一部第2課

開発一部の土井です。 Azureを使用するプロジェクトで、テスト環境がないため困ったことがありました。調査した結果、「Azurite」というローカル用のAzure Storage環境があることを知りました。この記事ではその使い方を紹介します。


前提条件

以下のツールを事前にインストールしておいてください。

  • Visual Studio (Community, Professional, または Enterprise)
  • Azure Storage Explorer

動作環境

  • Visual Studio Community 2022
  • .NET 7.0

Azuriteのインストール確認

Visual Studio 2022をインストールしている場合、Azuriteは既にインストールされています。

Exeファイルの場所

エディションファイルパス
CommunityC:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator
ProfessionalC:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator
EnterpriseC:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator

Azuriteのセットアップ手順

1. ローカルフォルダの作成

任意の場所に、Azure Storage環境用の空のフォルダを作成します。作成したフォルダのパスを控えてください。 画像1

2. コマンドプロンプトの起動

コマンドプロンプトを起動し、Azuriteのexeファイルがあるディレクトリまで移動します。

画像2

3. Azuriteの起動

以下のコマンドを実行してください。

Azurite.exe -l "フォルダパス" --skipApiVersionCheck
例:
Azurite.exe -l C:\LocalAzureStorage –skipApiVersionCheck

画像3

正常に起動すればセットアップ成功です。


動作テスト

1. Azure Storage Explorerの確認

Azure Storage Explorerを起動し、ローカルのAzuriteストレージアカウントが表示されることを確認します。表示されない場合は、手動でアカウント情報を設定してください。

画像4

2. 動作確認用コードの実装

動作確認のためのコードをC#にて実装します。
内容は「teststorage」という名前のコンテナを作成し、その中に「testfile.txt」という名前のtxtファイルを作成します。そのあとファイルの中に文字を書き込むというような内容のものです。
コンテナ作成時にはアルファベットの大文字を使用するとエラーになりますので、注意してください。

BlobEvent.cs
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Specialized;
using System.Text;

namespace BlobTest
{
public class Program
{
public static async Task Main(string[] args)
{
string connString =
"DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;" +
"AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;" +
"BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" +
"QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;" +
"TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;";

string containerName = "teststorage";
BlobServiceClient blobServiceClient = new BlobServiceClient(connString);
BlobContainerClient blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);

string fileName = "testfile.txt";
AppendBlobClient appendBlobClient = blobContainerClient.GetAppendBlobClient(fileName);

await blobContainerClient.CreateIfNotExistsAsync();
await appendBlobClient.CreateIfNotExistsAsync();

StringBuilder text = new StringBuilder("Hello, World");
var bytes = Encoding.UTF8.GetBytes(text.ToString());

using (var stream = new MemoryStream(bytes))
{
appendBlobClient.AppendBlock(stream);
}
}
}
}

3. コードの実行

実行後、Azure Storage Explorerを確認してください。

  • 「teststorage」という名前のコンテナーが作成されます。

画像5 画像6

  • 「testfile.txt」というファイルが作成されており、中身に「Hello, World」と出力されます。

画像7


まとめ

これでローカル環境でAzure Storageの動作確認ができるようになります。テスト環境がない場合でも、効率的な開発が可能です。

生成AIでフルスタックWebアプリが作成できるbolt.newで社内ポータルサイトを作成してみた

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部の箕浦です。
以前、「v0」という WEB アプリの UI を生成 AI を使って作成するサービスを紹介しましたが、
今回は「bolt.new」という生成 AI を使って、フルスタックのアプリケーションが作成できる驚きのサービスが登場したので、試してみました。
無料でも利用可能ですが、現時点では、無料プランでは 1 日あたり 15 万トークン、1 か月あたり 100 万トークンに制限があり、
無料枠では意外とすぐに使い切ってしまうので、注意が必要です。

bolt.new の概要

bolt.new は、フルスタック Web アプリケーション開発を劇的に簡素化する AI 駆動型の開発ツールです。
ChatGPT のように、ユーザーが自然言語で指示を出すだけで、ブラウザ上でアプリの作成からデプロイ、管理までをシームレスに実現できるのが特徴です。
特に、プロトタイピングに時間をかけられないプロジェクトには、非常に便利です。

主な特徴

  1. AI による自動コード生成: ユーザーの指示に基づき、AI が自動でコードを生成してくれるため、手作業でのコーディング時間を大幅に削減できます。

  2. ブラウザ内でのフルスタック開発: StackBlitz の WebContainers を統合し、ブラウザ上で完結した開発環境を提供することで、ローカル環境の構築が不要です。

  3. 多様なフレームワークに対応: Vite や Next.js など、幅広いフレームワークをサポートしているため、様々な開発ニーズに応じた選択が可能です。

  4. 開発環境の完全制御: AI モデルがファイルシステム、Node サーバー、パッケージマネージャーなど開発環境全体を制御でき、開発作業がスムーズに進みます。

  5. 迅速なデプロイ: チャットインターフェースから直接プロダクションにデプロイ可能で、短時間でのリリースが実現します。

bolt.new の機能

  1. プロンプトベースの開発: ユーザーが自然言語で要望を伝えると、AI がその指示に基づいてアプリケーションを構築します。

  2. リアルタイムの機能追加・修正: 開発中のアプリに対して、プロンプトで追加の機能や変更を指示できるため、迅速に対応が可能です。

  3. フレームワーク指定開発: 特定のフレームワークを指定して Web サイトやアプリを生成できるため、技術スタックに応じた最適な設定が行えます。

  4. 統合開発環境: StackBlitz との連携により、オンラインのコードエディタでプロジェクトの編集やデプロイが簡単に行える点も便利です。

bolt.new で社内ポータルサイトを作成してみた

試しに社内向けのポータルサイトを作成しました。
今回はデザインに関しては大きくこだわらず、シンプルな構成で短時間に作り上げることを目指しました。

ポータルサイトの概要

作成した社内ポータルサイトには以下の主要機能を実装しました:

  • ダッシュボード: 各機能へのアクセスや通知の要約を確認できるページ

  • お知らせ掲示板: 社内全体への重要な情報の告知やイベント通知

  • 月例会ルール・議事録: 定例会議でのルールや議事録を共有する機能

開発プロセス

  1. bolt.new にアクセスし、新規プロジェクトを開始

    アプリの作成手順は非常にシンプルで、ChatGPTのようにプロンプトから作成したいアプリの内容を指示するだけです。

    bolt.png

  2. AI への指示

    今回は以下のように指示しました。\

    siji1.png

  3. 動作確認

    指示を送ると、boltがアプリを頑張って作成してくれています。
    ファイルの構成はデフォルトではVite+React+typeScriptで作成されるようです。

    code.png

    作成完了すると、画面左に作成したアプリの機能の概要を説明してくれています

    gaiyo.png siyouhou.png

    プレビューを確認するとログイン画面ができています。

    login.png

    早速、説明欄の一般ユーザーでログインしてみます。 ダッシュボードに、お知らせや議事録が一覧できる画面ができています。

    home.png

    今後は、ログアウトして、登録できる管理画面を確認します。

adminlogin.png

画面上部に「Admin」ボタンが増えています。

adminhome.png

適当に投稿してみます。

post1.png post2.png

投稿が反映されていませんでした。

adminhome.png

  1. AI に追加指示

    そこで、さらに追加で以下の指示をしてみました\

    siji2.png

    要求通り実装してくれたようです\

    gaiyo2.png

    再度、同じ投稿をして確認すると、今度は正しく投稿が反映されました。

afteradmin.png

  1. デプロイ

    bolt.new の画面の右上にある「Deploy」ボタンからデプロイすることも可能です。デプロイ手順は非常にシンプルで、短時間でリリースが完了しました。
    deploy.png

    デプロイ先はNetlifyにデプロイされるようです。

    今回作成したものと全く同じではないですが、boltで作成したサイトを以下へデプロイしています。
    https://chimerical-pithivier-8ab33b.netlify.app

  2. プロジェクトのダウンロード

    「open the StackBlitz」というボタンを押すと、StackBlitz でプロジェクトが開き、こちらでソースコードを直接編集することも、ローカルにダウンロードすることも可能です。

stackbriz.png

開発の所感

bolt.new を使用した開発プロセスは予想以上に迅速で、従来のコーディング方法と比較して以下のようなメリットを感じました:

  • 開発時間の大幅な短縮:指示を与えるだけで基本的なコードが自動生成されるため、短時間でプロトタイプが完成します。

  • シンプルな指示で実装可能:複雑なコードを書くことなく、機能を実装できます。

  • コードの品質:自動生成されるコードの品質が一定レベル以上であるため、開発初期段階から安定したコードが提供されます。

  • 統合開発:フロントエンドとバックエンドを統合的に開発でき、StackBlitz を通してコードをダウンロード可能で、自身のプロジェクトとしても管理がしやすいです。

課題と改善点

一方で、以下の課題も見つかりました:

  • 細かいカスタマイズには従来のスキルが必要:bolt.new が自動生成するコードは基本的な構成に限られ、細かい UI やビジネスロジックの調整には手動の編集が必要です。

  • 大規模なアプリケーションには不向きな点:特に大規模なアプリケーションを構築する際、全体のコードの構造を理解するのが難しくなる場合があります。

まとめ

bolt.new を使用して社内ポータルサイトを開発してみて、AI による開発支援の大きな可能性を感じました。
特に、短時間でプロトタイプを作成する場面や、迅速な開発が求められる小規模プロジェクトにおいては非常に有効なツールであると感じます。
今回はデザインに関する指示は特に行いませんでしたが、もう少し細かく指示を与えれば、ある程度のデザインも実装されると考えられます。
デプロイまで行えますが、本格的な運用にはもう少し調整が必要です。
しかし、プロジェクトのひな型として利用し、ダウンロードして自身の環境で微調整を行う使い方は非常に便利です。
今後のアップデートでさらに機能が充実すれば、より複雑なプロジェクトや商用アプリケーションにも適用できるようになるかもしれません。

タスク管理ツール「Planner」を使ってみた

西
ディアシステム(株)開発一部第4課

こんにちは。開発一部の西です。 タスク管理ツールのPlannerを使ってみましたので、レポートしたいと思います。

チームで作業するならタスク管理ツールは必須アイテム

チーム内でタスクの進捗管理をし、その内容を共有できるツールを利用されている方も多いかと思います。
Web会議では、タスク管理ツールの画面を共有しながら進捗確認することもよくありますよね。
すぐに思いつくツールとして、Notion、Slack、Backlogなどがあります。
それらの多くは、個別にユーザ登録をして、Webサイトから利用、またはアプリケーションをPCにインストールして利用することになります。
ところが、所属チーム内にそれらが導入されておらず、利用したくても簡単に導入できない環境で作業されている方も少なくありません。
そこで今回は、広く利用されているMicrosoft Teamsの環境から、簡単にタスク管理が利用できるPlannerをご紹介します。

TeamsのタブにPlannerを追加する

TeamsはWebブラウザから利用することもできますが、ここではアプリ版を使用して説明していきます。
それでは早速、チャネルのタブにPlannerを追加する手順をみていきましょう。
まずは、Teamsの画面中央上部にある「+」をクリックしてタブを追加していきます。

画像1.png

表示された検索ダイアログより「Planner」と入力してアプリを検索し、そのアイコンを選択します。

画像2.png

するとPlannerの初期設定ダイアログが表示されますので、タブ名を入力して「保存」をクリックします。
今回は、タブ名「タスク管理」として作成します。

画像3.png

保存ボタンを押下すると「タスク管理」タブが画面上部に追加され、タスク管理を開始できる環境が整いました。以上で準備は完了。簡単ですよね。

画像4.png

タスクを登録してみる

次にタスクを登録してみます。画面上部の「グリッド」を選択すると以下のようなレイアウトとして表示されます。
そこで「+ 新しいタスクの追加」を選択すると最下行に新規タスク用の行が追加されます。
項目は、タスクの「タイトル」、担当者の「割り当て」、「開始日」、「期限」、「バケット」、「進捗」、「優先度」、「ラベル」から構成されています。
ちなみに「ラベル」は、タスク毎に共通情報のラベル名を決めて付与しておくことで、タスクが増えていった際に管理しやすくなります。

画像5.png

また、画面上部の「ボード」を選択すると、以下のように「バケット」単位のレイアウトになります。

画像6.png

バケットには、そのタスクがどのような区分なのかを設定しておくことで、区分別に状況整理ができるかと思います。
例えば、プロジェクトのサブシステム毎にバケットを作成しておくと、各サブシステムの残課題や進捗状況が把握しやすくなると思います。
新しいバケットを追加するには、画面右側にある「新しいバケットの追加」を選択してバケット名を入力することで増やすことができます。

メール通知機能も備わっている

タスクに担当者としてアサインされた場合や期限に対するリマインドとして担当者へメール通知される機能も備わっています。
具体的には、以下のタイミングでメール通知されます。
・他のユーザが自分にタスクを割り当てたとき
・期限を設定し、その期限が近付いたとき、および期限超過したとき
・割り当てたタスクのコメント欄(下記イメージ図参照)にメッセージが追加されたとき

画像7.png

最後に

タスク管理ツールのPlannerを紹介しましたが、いかがでしたでしょうか。
すでにTeamsを利用されている方なら簡単に導入できますので、ぜひタスク管理ツールの候補の1つとしてご検討ください。

プログラミング学習サイト「Progate」を利用してみた感想

磯村
ディアシステム(株)開発一部第4課

こんにちは。開発一部の礒村です。
今回は私が、Progateというプログラミング学習サイトを利用してみた感想を述べたいと思います。

【今までの学習の問題点】

私は、プログラミングを学習する中で今までは、参考書で学習することがほとんどでした。参考書を読み進めていきながら自分で手を動かして学んでいく、という形で進めてきました。
参考書を読み進めていく中で、「あれ?これってどういう意味だろう」と私が疑問に思うところがあったとしても、参考書にもよりますが、「知っていることが前提」であるかのように説明が省かれていることがありました。 私のようなかなり初心者レベルの疑問を抱く人は、参考書に前提として書いてあることがそもそもわからず、最終的に読み切った時点では「あまりよくわからなかった」
となる経験をしたことがあるのではないでしょうか。
参考書を購入する時点で、自分のレベルにあった参考書を選ぶことができるとよいですが、プログラミング学習に限らず、自分のレベルにドンピシャな参考書を選ぶことができたことってあまりない気がします。(選べる時点である程度のレベルではある気がします)

【Progateの利点】

私がなぜProgateで学習を順調に進めることができたのかというと、
Progateはすべてのコースを学習するには有料のプランに加入する必要がありますが、
最初はお試しのような感じで、どの言語コースも無料で学習できるページがあります。
私は、まず無料でProgateの学習を始めてみました。
Progateを利用してみてまず思ったことが、基礎の基礎から教えてくれる本当に初心者向けの学習サイトであると思いました。
しっかり段階を踏んで説明されていたので、途中で分からなくなることがなく進めることができました。 今までは、“初心者向け”という記載がある参考書を読んでいても、どこかで説明が省略されており疑問が生じることが多くありました。
Progateはそのような疑問が発生することなく学習できました。
また、Progateの進め方は、「何枚かのスライドで重要ポイントを学習し、その学習した内容を使用して自分でコーディングをする、そしてコースの最後にはその言語を使用した目標物を作成する」という流れでした。
スライド自体も簡潔で分かりやすくサクサクと進めることができました。

画像1.png

スライドの例(JavaScriptお試しコースより)

画像2.png

スライド最終ページのコーディングページの例

手順やコメントを参考にコーディングしていきます。
わからない箇所はスライドに戻って確認します。

【今後のProgateでの学習】

Progateのみでは、業務で使用するレベルの能力を身に着けることはできないかもしれませんが、理解できる元となる基礎の部分は身に着けることができると思います。
私は現段階で、Progateでは業務に関連する言語コースしか学習していませんが、
Progateにはほかにも主要な言語コースが揃っており、これからまだ学習していない言語コースも挑戦してみて、\自分の好みの言語や得意不得意を見つけたり、
プログラミング自体への理解や自身の興味を深めていくきっかけにしたいと思っています。

Progate URL:https://prog-8.com/

未経験から始める
システムエンジニア

一生モノのITスキルを身につけよう

あなたの経験とスキルを
ディアシステムで発揮してください!