.NET Core の DI サービスにおいて、ジェネリック型の DI を行う方法について調べてみました。
とりあえず以下のサイトでわかりやすく説明されています。
ASP.NET Core と書かれていますが、DI の機能は Microsoft.Extensions.DependencyInjection
で提供されているので、別に .NET Core のコンソールアプリなどでも使えます。
環境
- .NET Core 2.1
- Visual Studio 2017
サンプルコード
以下のようなインターフェイスがあるとします。
public interface IThing<T>
{
string GetName { get; }
}
このインターフェイスの実装を以下のようにしたとします。
public class GenericThing<T> : IThing<T>
{
public GenericThing()
{
GetName = typeof(T).Name;
}
public string GetName { get; }
}
これを DI サービスに登録する場合、以下のように書きます。
serviceCollection.AddSingleton(typeof(IThing<>), typeof(GenericThing<>));
注入されるクラスでは以下のように書きます。
public class Class1
{
private readonly IThing<Class1> _thing;
public Class1(IThing<Class1> thing)
{
_thing = thing;
Console.WriteLine(_thing.GetName);
}
}
以下メインメソッドのサンプルです。
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
// DI サービスへの登録
services.AddSingleton(typeof(IThing<>), typeof(GenericThing<>));
services.AddSingleton<Class1>();
// DI サービスのビルド
IServiceProvider serviceProvider = services.BuildServiceProvider();
var service = serviceProvider.GetService<Class1>();
Console.ReadKey();
}
出力結果
Class1
もう少し汎用的に
インターフェイスを以下のように定義しておけば、
public interface IThing<T> : IThing
{
}
public interface IThing
{
string GetName { get; }
}
注入されたオブジェクトを非ジェネリック型の変数に格納できます。
public class Class1
{
private readonly IThing _thing;
public Class1(IThing<Class1> thing)
{
_thing = thing;
Console.WriteLine(_thing.GetName);
}
}