もくじ
https://tera1707.com/entry/2022/02/06/144447
やりたいこと
以前の記事で、Ioc
と ServiceCollection
を使って、DI(Dependency Injection)をやったが、そのときコンストラクタで受けるクラスは、それぞれ別のインターフェースを実装するクラスだった。
同じインターフェースを実装したクラスを複数受け取りたいときはどうしたらいいか?調べてみる。
まずこまったこと
下記のツールを作ってるときにおきたこと。
https://github.com/tera1707/FileVerUpTool
下記のコンストラクタのように、同じインターフェースを実装したクラスを3つ受け取りたかった。
public VersionReadWrite(ISearchSpecifiedExtFile ssef, IProjMetaDataHandler mdh1, IProjMetaDataHandler mdh2, IProjMetaDataHandler mdh3) { _finder = ssef; _sdkcsproj = mdh1; _dfwcsproj = mdh2; _cppproj = mdh3; }
そのために、services.AddSingleton
を、下記のように3回読んで、3つ分登録しようとした。
services.AddSingleton<IProjMetaDataHandler, SdkTypeCsprojHandler>(); services.AddSingleton<IProjMetaDataHandler, DotnetFrameworkProjHandler>(); services.AddSingleton<IProjMetaDataHandler, CppProjHandler>();
そうすると、コンストラクタで受け取るIProjMetaDataHandler
を実装したクラスが、3つとも、3個目に登録したCppProjHandler
になってしまった。
おそらく、前の二つは、最後のCppProjHandler
に後勝ちで上書きされたものと思われる。
なので、今回は下記のようにした。
登録する個所
services.AddSingleton<IProjMetaDataHandler[]>(x => new IProjMetaDataHandler[] { new SdkTypeCsprojHandler(), new DotnetFrameworkProjHandler(), new CppProjHandler() });
使うコンストラクタ
public VersionReadWrite(ISearchSpecifiedExtFile ssef, IProjMetaDataHandler[] handlers) { _finder = ssef; _sdkcsproj = handlers[0]; _dfwcsproj = handlers[1]; _cppproj = handlers[2]; }
これで、うまく、同じインターフェースを実装したクラスを3つ分受け取ることができた。