Edited at

[WPF]prism.unity(6.3.0)の簡単な実装サンプル②(登録~依存性注入まで)(RegisterType使用)


prism.unity関連


試した環境

モノ
バージョン

VisualStudio
2017

Prism.Unity
6.3.0


やりたいこと

以前の記事で、RegisterInstanceを使ってUnityのDIコンテナにインスタンスを登録し、それを別のクラスに注入、ということを試した。その時に、別のやり方(RegisterTypeを使ったやり方)もあるようだったので、そちらのやり方もメモしておく。

RegisterInstanceとRegisterTypeの違いは、別ページ参照。


サンプルを元に考える

以前と同じように、こちらをベースにさせていただいています。

using Microsoft.Practices.Unity;

using System;

namespace ConsoleApp10
{
class Program
{
static void Main(string[] args)
{
// DI コンテナを生成
UnityContainer container = new UnityContainer();

Console.WriteLine("[Main] 名前を指定してインスタンスを登録する。");

// 名前を指定してインスタンスを登録(RegisterType()) //ここではDogやCatのコンストラクタは呼ばれない(newしてないから、注入されるときにnewされる)
container.RegisterType<IAnimal, Cat>();
container.RegisterType<IAnimal, Dog>();

// 依存性を注入する
Console.WriteLine("[Main] 依存性を注入する。");
var person = container.BuildUp<Person>(new Person());

// ペットを呼ぶ
Console.WriteLine("[Main] ペットを呼ぶ。");
person.CallPet();

Console.ReadLine();
}
}

// 動物インターフェース
public interface IAnimal
{
void Cry();// 鳴き声を出力する
}

// ネコ(IAnimalインターフェースの実装)
public class Cat : IAnimal
{
public Cat() => Console.WriteLine(" 猫 コンストラクタ");
public void Cry() => Console.WriteLine("ニャ~");
}

// イヌ(IAnimalインターフェースの実装)
public class Dog : IAnimal
{
public void Cry() => Console.WriteLine("バウ!");
public Dog() => Console.WriteLine(" 犬 コンストラクタ");
}

// 依存性を注入されるクラス
public class Person
{
[Dependency]
public IAnimal Pet { get; set; }

// ペットを呼ぶ
public void CallPet() => Pet.Cry();
}
}


コードの流れ


  • 依存性の登録~注入までは、下記のような流れで行う。



    • UnityContainer container = new UnityContainer();DIコンテナを生成する


    • container.RegisterType<インターフェース, インターフェースを実装したクラス>();クラスをコンテナに登録する


    • container.BuildUp<注入先クラス>(new 注入先クラス());で、登録したコンテナを使って注入先クラスをnewすると同時に依存性(注入先で使うクラス達)を注入する

    • 注入先クラスで、注入されたクラス(のインスタンス)を使う




動作メモ


インスタンス化する(=コンストラクタが呼ばれる)タイミング


  • 登録時は、インターフェースとそれを実装したクラスのペアを登録しているだけなのでnewされない。
    依存性を注入するときに、都度newされる。

  • 複数のクラスに注入されるときは、その都度newされる。(全クラスで同じインスタンスを見るわけではない)


コンストラクタについて

DogやCatクラスに、引数のあるコンストラクタを作ると、なぜかvar person = container.BuildUp<Person>(new Person());のところで落ちてしまう。(「使えるコンストラクタがない」旨の例外発生)

→なぜ?