web-dev-qa-db-ja.com

Asp.Net Core:複数のインターフェイスとライフスタイルシングルトンで実装を登録する

次のインターフェイスとクラスの定義を考慮してください。

public interface IInterface1 { }
public interface IInterface2 { }
public class MyClass : IInterface1, IInterface2 { }

MyClassの1つのインスタンスを次のような複数のインターフェイスに登録する方法はありますか。

...
services.AddSingleton<IInterface1, IInterface2, MyClass>();
...

MyClassのこの単一インスタンスを、次のような異なるインターフェースで解決します。

IInterface1 interface1 = app.ApplicationServices.GetService<IInterface1>();
IInterface2 interface2 = app.ApplicationServices.GetService<IInterface2>();
39
Maxim

定義によるサービスコレクションは、ServiceDescriptorsのコレクションであり、サービスタイプと実装タイプのペアです。

ただし、次のような独自のプロバイダー関数を作成することで、これを回避できます(user7224827に感謝)。

services.AddSingleton<IInterface1>();
services.AddSingleton<IInterface2>(x => x.GetService<IInterface1>());

以下のオプション:

private static MyClass ClassInstance;

public void ConfigureServices(IServiceCollection services)
{
    ClassInstance = new MyClass();
    services.AddSingleton<IInterface1>(provider => ClassInstance);
    services.AddSingleton<IInterface2>(provider => ClassInstance);
}

別の方法は次のとおりです。

public void ConfigureServices(IServiceCollection services)
{
    ClassInstance = new MyClass();
    services.AddSingleton<IInterface1>(ClassInstance);
    services.AddSingleton<IInterface2>(ClassInstance);
}

同じインスタンスを提供するだけです。

40
juunas

User7224827の回答をラップして、元の目的のAPIに一致するNice拡張メソッドを作成できます。

    public static class ServiceCollectionExt
    {
        public static void AddSingleton<I1, I2, T>(this IServiceCollection services) 
            where T : class, I1, I2
            where I1 : class
            where I2 : class
        {
            services.AddSingleton<I1, T>();
            services.AddSingleton<I2, T>(x => (T) x.GetService<I1>());
        }
    }
3
daw