.NET Core DI 多种接口

问题描述 投票:0回答:1

有一些服务及其接口:

public class ServiceA: IServiceA
{}

public class ServiceB: IServiceB
{}

public class ServiceC: IServiceC
{}

他们的方法都是一样的

public Task ResetAsync(CancellationToken cancellationToken = default)
{
   // Reset something
}

我已经为此方法创建了接口 IResettable

public interface IResettable
{
    Task ResetAsync(CancellationToken cancellationToken = default);
}

然后我在 DI 中注册了我的所有服务,如下:

services.AddSingleton<IServiceA, ServiceA>();
services.AddSingleton<IServiceB, ServiceB>();
services.AddSingleton<IServiceC, ServiceC>();

现在我可以为我的服务使用两种类型的继承:

IServiceA : IResettable
IServiceB : IResettable
IServiceC : IResettable

ServiceA : IServiceA, IResettable
ServiceB : IServiceB, IResettable
ServiceC : IServiceC, IResettable

现在我想通过 cron 表达式从 IResettable 为我的所有服务调用 ResetAsync,如下所示:

public class ResetService(
    IEnumerable<IResettable> services) : IResetService
{
    private readonly IEnumerable<IResettable> _services = services;

    public async Task DoWorkAsync(CancellationToken cancellationToken = default)
    {
        foreach (var service in _services)
        {
            await service.ResetAsync(cancellationToken);
        }
    }
}

我可以按如下方式添加我的服务:

services.AddTransient<IResettable, ServiceA>();
services.AddTransient<IResettable, ServiceB>();
services.AddTransient<IResettable, ServiceC>();

services.TryAddSingleton<IResetService, ResetService>();

我可以在

ResetAsync
中为他们打电话
ResetService
,但这些不会是注册为
IServiceA
IServiceB
IServiceC
的服务。这将是新实例。

所以,我的问题是:

  1. 这些注册之间的全局差异是什么:
    services.AddSingleton<IServiceA, ServiceA>();
    
    services.AddSingleton<ServiceA>();
    
  2. 我应该使用哪种类型的继承以及为什么
    ServiceA : IServiceA, IResettable
    
    // or
    
    ServiceA : IServiceA
    
    IServiceA : IResettable
    
  3. 还有主要问题:如何将
    ServiceA
    的相同实例注册为
    IServiceA
    IResettable
    (使用 .Net Core DI),以便在其他服务中使用
    IServiceA
    并在
     中使用 
    IEnumerable<IResettable>
     ResetService
    为所有人致电
    ResetAsync
    IResettable
    服务?
c# .net dependency-injection interface
1个回答
0
投票

根据您实现服务类的方式,您可以使用类似工厂方法来注册它们

interface IServiceA : IResetable 
{}
class ServiceA : IServiceA
{}

services
    .AddSingleton<IServiceA, ServiceA>()
    .AddSingleton<IResetable>( provider => provider.GetRequiredService<IServiceA>() );

interface IServiceA
{}
class ServiceA : IServiceA, IResetable
{}

services
    .AddSingleton<ServiceA>()
    .AddSingleton<IServiceA>( provider => provider.GetRequiredService<ServiceA>() )
    .AddSingleton<IResetable>( provider => provider.GetRequiredService<ServiceA>() );
© www.soinside.com 2019 - 2024. All rights reserved.