Asp.Net Core:注册实现多个接口和生活方式Singleton

问题描述 投票:37回答:2

考虑以下接口和类定义:

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>();
c# dependency-injection asp.net-core inversion-of-control
2个回答
40
投票

根据定义,服务集合是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);
}

我们只提供相同的实例。


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>());
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.