There are some services and their interfaces:
public class ServiceA: IServiceA
{}
public class ServiceB: IServiceB
{}
public class ServiceC: IServiceC
{}
All of them have the same method
public Task ResetAsync(CancellationToken cancellationToken = default)
{
// Reset something
}
I've created the interface IResettable for this method
public interface IResettable
{
Task ResetAsync(CancellationToken cancellationToken = default);
}
Then I registered all of my services in the DI as follows:
services.AddSingleton<IServiceA, ServiceA>();
services.AddSingleton<IServiceB, ServiceB>();
services.AddSingleton<IServiceC, ServiceC>();
Now I can use two types of inheritance for my services:
IServiceA : IResettable
IServiceB : IResettable
IServiceC : IResettable
or
ServiceA : IServiceA, IResettable
ServiceB : IServiceB, IResettable
ServiceC : IServiceC, IResettable
And now I want to call ResetAsync from IResettable by cron expression for all of my services, something like this:
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);
}
}
}
I can add my services as follows:
services.AddTransient<IResettable, ServiceA>();
services.AddTransient<IResettable, ServiceB>();
services.AddTransient<IResettable, ServiceC>();
services.TryAddSingleton<IResetService, ResetService>();
and I can call ResetAsync
for them in the ResetService
, but these will not be the services that were registered as IServiceA
, IServiceB
, IServiceC
. It will be new instances.
So, my questions are:
services.AddSingleton<IServiceA, ServiceA>();
services.AddSingleton<ServiceA>();
ServiceA : IServiceA, IResettable
// or
ServiceA : IServiceA
IServiceA : IResettable
ServiceA
as IServiceA
and as IResettable
(using .Net Core DI) to use IServiceA
in other services and to use IEnumerable<IResettable>
in the ResetService
to call ResetAsync
for all IResettable
services?You can only register a single type per registration.
Add...<IServiceA, ServiceA>()
will register the interface type IServiceA
with its implementation of class ServiceA
.
Add..<ServiceA>()
will register the class type ServiceA
.
You can only resolve the registered types and not the type the registered types implement or inherit from.
It depends on you. Choose what is best to solve your problem.
Depending on how you implement the service classes you register them with a factory method like
interface IServiceA : IResetable
{}
class ServiceA : IServiceA
{}
services
// register the type IServiceA
.AddSingleton<IServiceA, ServiceA>()
// register the type IResetable
.AddSingleton<IResetable>( provider => provider.GetRequiredService<IServiceA>() );
or
interface IServiceA
{}
class ServiceA : IServiceA, IResetable
{}
services
// register the type ServiceA
.AddSingleton<ServiceA>()
// register the type IServiceA
.AddSingleton<IServiceA>( provider => provider.GetRequiredService<ServiceA>() )
// register the type IResetable
.AddSingleton<IResetable>( provider => provider.GetRequiredService<ServiceA>() );