LoginSignup
4
5

More than 5 years have passed since last update.

軽量DIコンテナ BtInjector を作ってみた

Last updated at Posted at 2017-06-15

DIコンテナを作ってみた

パフォーマンスがイマイチor要件に合わないコンテナが多かったので作ってみた
https://github.com/chalharu/BtInjector
nugetでBtInjectorで検索すると使えます

使い方

コンテナの登録

// まずコンテナインスタンスの作成
var container = new Container();

// シングルトンインスタンスの登録
// インターフェイス - 実体の型を登録
container.For<IService1>().As<Service1>(Lifecycle.Singleton);
// インスタンスを登録
container.For<IService2>().As(service2);
// ラムダ式で登録
container.For<IService3>().As(() => new Service3(), Lifecycle.Singleton);
container.For<IService4>().As((IService3 service3) => new Service4(service5), Lifecycle.Singleton);

// 都度生成の場合
// インターフェイス - 実体の型を登録
container.For<IService6>().As<Service6>(Lifecycle.Transient);
// ラムダ式で登録
container.For<IService7>().As(() => new Service7(), Lifecycle.Transient);
container.For<IService8>().As((IService7 service7) => new Service8(service7), Lifecycle.Transient);

// スレッド単位生成の場合
// インターフェイス - 実体の型を登録
container.For<IService9>().As<Service6>(Lifecycle.ThreadLocal);
// ラムダ式で登録
container.For<IService10>().As(() => new Service10(), Lifecycle.ThreadLocal);
container.For<IService11>().As((IService10 service10) => new Service11(service10), Lifecycle.ThreadLocal);

インスタンスの生成

// 通常通り生成
container.GetInstance<IService1>();
// 生成するデリゲートを出力
container.GetInstance<Func<IService6>>();
// 遅延生成
container.GetInstance<Lazy<IService7>>();

ポイント

  • Funcで生成できる
  • ラムダ式で登録できる
  • かなり軽量(のつもり)
  • いろんなプラットフォームに対応
    • .NET Framwork 4.0
    • PCL(Profile 5)
    • iOS(実機がないので不明だがとりあえずFullAOTで動く)
    • .NET Standard 1.1

DIコンテナを評価してみる

参考: http://www.nuits.jp/entry/ioc-battle-in-2017

前提条件

  • MacBook Pro Retina 2014
  • Memory 8G
  • Mono 5.0.0
  • .NET Framework 4.6.2ターゲット

評価内容

  • Singlton時のコンテナ登録時間
  • Singlton時の初回インスタンス取得時間
  • Singlton時の2回目以降インスタンス取得時間(100万インスタンス)
  • インスタンス都度生成時のコンテナ登録時間
  • インスタンス都度生成時の初回インスタンス取得時間
  • インスタンス都度生成時の2回目以降インスタンス取得時間(100万インスタンス)

変更点

  • 初回インスタンス取得時間の追加
    • 初回のインスタンス取得が非常に重たいコンテナが多く、別途測定する必要があると思われる
  • Singletonと都度生成のそれぞれでAppDomainを生成した
    • 型がキャッシュされている場合が多いため

評価結果

Container Singleton - Registartion[ms] Singleton - Resolve first[ms] Singleton - Resolve[ms] Transient - Registartion[ms] Transient - Resolve first[ms] Transient - Resolve[ms]
new Operator 0.11 0.47 17.09 0.10 0.47 175.38
BtInjector 3.18 26.20 79.25 3.19 25.15 299.24
BtInjector Lambda 4.60 2.99 79.72 4.43 2.70 515.70
DryIoc.dll 26.22 16.85 35.71 26.45 20.40 202.12
AutoFac 38.48 56.94 758.52 39.45 63.03 35,440.41
AutoFac Lambda 37.71 7.14 745.74 37.09 5.59 10,345.82
StructureMap 30.50 105.62 1,026.37 27.60 98.85 7,869.01
SimpleInjector 29.29 70.27 73.17 32.33 64.46 257.75
Unity 24.60 90.24 1,041.28 23.61 86.98 24,289.29

BtInjectorはコンテナの登録・初回生成を含めるとかなり健闘しているはず。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5