Prism関連
https://qiita.com/tera1707/items/4fda73d86eded283ec4f#prism%E9%96%A2%E9%80%A3wpfxaml
試した環境
モノ | バージョン |
---|---|
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());
のところで落ちてしまう。(「使えるコンストラクタがない」旨の例外発生)
→なぜ?