同じインタフェースを実装していたり、同じ抽象クラスをベースとしているクラスをコレクションとして DI したかったので、やり方を調べてみました。
ASP.NET Core における DI サービス自体の説明については省略します。
環境
- Visual Studio 2017
- ASP.NET Core 2.1
DI したいクラス
サンプルとして、ここでは以下のような ISample
を実装した3つのクラスを DI します。
public interface ISample
{
string Name { get; }
}
public class Sample1 : ISample
{
public string Name { get; } = "Sample1";
}
public class Sample2 : ISample
{
public string Name { get; } = "Sample2";
}
public class Sample3 : ISample
{
public string Name { get; } = "Sample3";
}
DI サービスへの登録
IServiceCollection
に対してサービスの登録を行います。
ASP.NET Core MVC のテンプレートから作成した場合は、Startup.cs
の ConfigureServices
メソッドで行います。
方法はいろいろあるかもしれませんが、ここでは例として以下の方法を挙げます。
その1
同じ型 ISample
に対して複数回登録を行います。
services.AddSingleton<ISample, Sample1>();
services.AddSingleton<ISample, Sample2>();
services.AddSingleton<ISample, Sample3>();
その2
型として IEnumerable<T>
を指定すると、一括で登録が行えます。
services.AddSingleton<IEnumerable<ISample>>(new List<ISample>
{
new Sample1(),
new Sample2(),
new Sample3()
});
DI の仕方
コンストラクタで IEnumerable<T>
として受け取るだけです。
public HomeController(IEnumerable<ISample> samples)
{
foreach (var sample in samples)
Debug.WriteLine(sample.Name);
}
DI した側で、実体を区別したい場合
別記事に書いたので、以下を参考にしてください。