UnityContainer に登録したインスタンスを取り出す

はじめに

仕事で Unity を触る機会ができたので、やったことをエントリにしていきます。

今回は構成ファイルを使っていません。依存性も注入していません。DI コンテナに登録したインスタンスを取り出すだけの簡単なサンプルです。

まずインタフェースを用意

DataSet を取得するメソッドのみ定義します。

public interface IMasterManager
{
    DataSet Read();
}

インタフェースを実装するクラスを複数用意

得意先・仕入先・商品の3種類を用意します。

// 得意先用
public class CustomerManager : IMasterManager
{
    public DataSet Read()
    {
        return new DataSet("Customer");
    }
}

// 仕入先用
public class SupplierManager : IMasterManager
{
    public DataSet Read()
    {
        return new DataSet("Supplier");
    }
}

// 商品用
public class ProductManager : IMasterManager
{
    public DataSet Read()
    {
        return new DataSet("Product");
    }
}

名前の付いた空の DataSet を返しているだけです。

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

次の2つを追加します。

  • Microsoft.Practices.Unity.dll
  • Microsoft.Practices.ObjectBuilder2.dll

Unity Container を使ってみます

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

    // 名前を指定してインスタンスを登録
    container.RegisterInstance<IMasterManager>("Customer", new CustomerManager());
    container.RegisterInstance<IMasterManager>("Supplier", new SupplierManager());

    // 名前を指定せずにインスタンスを登録
    container.RegisterInstance<IMasterManager>(new ProductManager());

    // 得意先を取得
    IMasterManager manager = container.Resolve<IMasterManager>("Customer");
    Console.WriteLine(manager.Read().DataSetName);

    // 仕入先を取得
    manager = container.Resolve<IMasterManager>("Supplier");
    Console.WriteLine(manager.Read().DataSetName);

    // 名前を指定せずにインスタンスの取得を試みる
    manager = container.Resolve<IMasterManager>();
    Console.WriteLine(manager.Read().DataSetName);

    Console.ReadLine();
}

このコードを実行すると次の結果が出力されます。

Customer
Supplier
Product

ちなみに、すべてのインスタンスが名前を指定して登録されていた場合、

manager = container.Resolve<IMasterManager>();

のところで例外が発生します。

また、ResolveAll で複数のインスタンスを取得できます!

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

    // 名前を指定してインスタンスを登録
    container.RegisterInstance<IMasterManager>("Customer", new CustomerManager());
    container.RegisterInstance<IMasterManager>("Supplier", new SupplierManager());

    // 名前を指定せずにインスタンスを登録
    container.RegisterInstance<IMasterManager>(new ProductManager());

    // 登録したインスタンスの中から IMasterManager を実装するものをすべて取得する
    IEnumerable<IMasterManager> managers = container.ResolveAll<IMasterManager>();
    foreach (IMasterManager manager in managers)
    {
        Console.WriteLine(manager.Read().DataSetName);
    }

    Console.ReadLine();
}

このコードの実行すると次の結果になります。

Customer
Supplier

名前を指定せずに登録したインスタンスは取得されません。

最後に

今回は Unity Container に登録したインスタンスを取得しただけでした。まだ依存性を注入していませんね。

次はコードで依存性を注入してみます。