Asp.Net Core: реализация регистров с несколькими интерфейсами и стилем жизни Singleton
Учитывая следующие определения интерфейса и класса:
public interface IInterface1 { }
public interface IInterface2 { }
public class MyClass : IInterface1, IInterface2 { }
есть ли способ зарегистрировать один экземпляр MyClass
с несколькими интерфейсами вроде этого:
...
services.AddSingleton<IInterface1, IInterface2, MyClass>();
...
и разрешить этот единственный экземпляр MyClass
с различными интерфейсами, такими как:
IInterface1 interface1 = app.ApplicationServices.GetService<IInterface1>();
IInterface2 interface2 = app.ApplicationServices.GetService<IInterface2>();
Ответы
Ответ 1
Набор услуг по определению представляет собой набор ServiceDescriptor
s, которые представляют собой пары типа сервиса и типа реализации.
Однако вы можете обойти это, создав свою собственную функцию поставщика, что-то вроде этого (спасибо 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);
}
Где мы просто предоставляем один и тот же экземпляр.
Ответ 2
Вы можете обернуть ответ user7224827, чтобы создать хороший метод расширения, соответствующий вашему первоначальному желаемому API:
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>());
}
}