nikkie-ftnextの日記

イベントレポートや読書メモを発信

Pythonのdependency injectionフレームワーク injectorのExampleを素振り💉 おー、injector.getで依存が与えられた上でインスタンスができるぞ!

はじめに

ゆっくり歩いていこう。1 nikkieです

Pythondependency injectionフレームワークinjectorを少しだけ触りました。

目次

injector

ちょうぜつ本(『ちょうぜつソフトウェア設計入門』)7章を読んでいて、「PythonではDI(dependency injection)のライブラリにどんなものがあるんだろう」と気になりました。
調べる中で見つかったのがinjector2

リポジトリはこちら:

READMEのexampleに沿って手を動かしていきます。

動作環境

  • Python 3.11.4
  • injector 0.21.0
    • pip install injector

A Quick Example

https://github.com/python-injector/injector/tree/0.21.0#a-quick-example

2つのクラスInnerとOuterがあります。
Outerクラスのインスタンスは、属性にInnerクラスのインスタンスを持ちます。
これが「依存」ですね。

ちょうぜつ本から、インスタンスを作るのに必要な依存は外から与えてもらうようにするのがDIと理解しました。
Quick ExampleではOuterクラスのインスタンスに必要なInnerクラスのインスタンスが外から与えられるということです。
実際、injector.get(Outer)すると、Innerクラスのインスタンスが与えられてOuterクラスがインスタンスされています!3

これを可能にしているのが@injectデコレータ4
これってオートワイヤリングってことなんじゃないでしょうか。
デコレートした関数の型ヒントを使っているみたいです。

@inject@dataclassデコレータと一緒でも動作する例も示されています。

実行例:

% python quick_example.py
outer.inner.forty_two=42
outer_with_dataclass.inner.forty_two=42

A Full Example

https://github.com/python-injector/injector/tree/0.21.0#a-full-example

インメモリのSQLiteデータベースへの接続にinjectorを使う例です。

実行例:

% python full_example.py
[('dependency', 'injection'), ('hello', 'world')]

インメモリのデータベースにインサートしたデータが、keyの昇順(=アルファベット順)で取得されました。

DIはここ。

injector = Injector([configure_for_testing, DatabaseModule()])
handler = injector.get(RequestHandler)

injector.getRequestHandlerクラスのインスタンスが返されています(handler.get()でDBのレコードを取得)
すごそうな雰囲気ですが、まだ理解が追いついていない感じです(Injector([configure_for_testing, DatabaseModule()])ってどういうこと?)

  • RequestHandlersqlite3.Connectionインスタンスに依存
  • sqlite3.Connectionインスタンスを返すのがDatabaseModule(provider?)
    • DatabaseModuleConfigurationに依存
  • Configurationインスタンスを返すのがconfigure_for_testing関数(?)
    • binder.bindの意味がよく分かっておらず、宿題事項

終わりに

Pythondependency injectionフレームワーク injectorのREADMEにある2つの例を触りました。
あるクラスのインスタンス化に必要なインスタンスは、injectorによって型ヒントから与えられるようです。

これが、DI...! ちょうぜつ本にもありましたが、作り方は考えなくてよくなっているのですね。
DIの概念にまだ慣れていないので、完全に理解と言えるくらいまでまだまだ手を動かしたいところです

P.S. 10/20(金) 第7章「依存性注入」のちょうぜつ本_読書py!

次回ちょうぜつ本_読書py(Python使い視点でちょうぜつ本を読む、みんなのアウトプット中心の読書会)は10/20(金)です!

SQLはInjectionできると脆弱性なのでダメですが、DependencyはInjectionできると良いんです。

常連さんも、お久しぶりの方も、はじめましての方もDI(でえあい)に興味ある方、大歓迎です!
ぜひぜひお気軽にお越しください〜


  1. TVアニメ「であいもん」公式サイト
  2. こちらの記事がきっかけです。手を動かしたいな
  3. https://injector.readthedocs.io/en/latest/api.html#injector.Injector.get
  4. https://injector.readthedocs.io/en/latest/api.html#injector.inject