構成ファイルを記述して依存性を注入する

はじめに

先日はコードでの依存性注入を試したので、今回は構成ファイルを使ったサンプルを作成してみました。先日のサンプルが元になっています。

参照するアセンブリを追加

  • Microsoft.Practices.ObjectBuilder2
  • Microsoft.Pracitces.Unity

だけじゃなく

  • Microsoft.Practices.Unity.Configuration
  • System.Configuration

も追加。

Dependency 属性を修正

public class Person
{
    [Dependency]
    public IAnimal Pet { get; set; }

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

Dependency 属性で名前を指定するのをやめました。

構成ファイルを記述

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </configSections>
    <unity>
        <!--型の別名を定義-->
        <typeAliases>
            <typeAlias alias="IAnimal"
                       type="BuildUpSample.IAnimal, BuildUpSample"/>
            <typeAlias alias="Cat"
                       type="BuildUpSample.Cat, BuildUpSample"/>
            <typeAlias alias="Dog"
                       type="BuildUpSample.Dog, BuildUpSample"/>
        </typeAliases>
        
        <containers>
            <container name="Sample">
                <!--DI コンテナに登録する型を記述-->                
                <types>
                    <type type="IAnimal" mapTo="Dog"/>
                </types>
            </container>
        </containers>
    </unity>
</configuration>

typeAlias 要素で、型の別名を定義しています。type 要素では別名を使って、型のマッピングを記述しています。

依存性を注入!

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

    // 構成ファイルから unity セクションを読み込む
    UnityConfigurationSection section
        = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    // 構成ファイルの内容を適用する
    section.Containers["Sample"].Configure(container);
    
    Person person = new Person();

    // 依存性を注入する
    person = container.BuildUp<Person>(person);

    // ペットを呼ぶ
    person.CallPet();

    Console.ReadLine();
}

このコードの実行結果は次の通り。

バウ!

Dog クラスのインスタンスが注入されていますね。

構成ファイルを書き変えて見る

<type type="IAnimal" mapTo="Cat"/>

と書き変えて(再ビルドしないで)実行すると

ニャ〜

と出力されます。Cat クラスに切り替わりました。

別名を記述しなくてもいい

別名を記述せずに直接

<type type="BuildUpSample.IAnimal, BuildUpSample" mapTo="BuildUpSample.Cat, BuildUpSample"/>

と書いてもいいです。

まとめ

構成ファイルを書き変えるだけで呼び出すクラスを切り替えることができました。でも構成ファイル(設定ファイル)は古いやり方みたい…。現在の主流について調べないとなぁ〜。