Context
I have 5 services:
Service1 (no depends.)
Service2 (no depends.)
Service3 (Service1, Service2, IServiceProvider) : ISpecialService
Service4 (Service1, Service2, Service3) : ISpecialService
Service5 (Service1, Service3, Service4) : ISpecialService
They are all one-instance-per-app-life Singleton services. Normally you just add them as a singletons and BuildServiceProvider. However, in my case all ISpecialService
needs to be registered twice: as factory and as their own direct type, so direct injection via ctor:
public SomeOtherService(Service3 s3, Service4 s4) { }
still works. The problem is that if I just register them normally:
.AddSingleton<ISpecialService, Service3>()
.AddSingleton<Service3, Service3>()
this will give me 2 different instances of Service3 which defeats the point of a singleton. To have one instance I need to make instance manually, before registering Service3 and provide the instance as a parameter to AddSingleton method.
var s3 = new Service3(s1, s2, ?isp?);
.AddSingleton<ISpecialService, Service3>(s3) // same instance for contract work
.AddSingleton<Service3, Service3>(s3) // same instance
...
.BuildProvider()
And this is a problem because Service3
has IServiceProvider
as dependency. Normally, it is being handled by DI but in this case where I need to register SINGLE instance of it twice I cant seems to find a way to provide complete ISP instance to Service3 instance. If I build ISP I no longer can add any services, which is a dead end because Servcie3 later will need to request as a workaround for circular dependency without 99 intermediate empty pointless services in-between:
private readonly Service1 service1;
private readonly Service2 service2;
private Service4 service4;
private readonly IServiceProvider ISP;
public Service3 (Service1 s1, Service2 s2, IServiceProvider isp)
{
//assign depenencies
}
public Startup()
{
//workaround for circular dependency
service4 = ISP.GetServic<Service4>()
}
The reason why I need to register Service 3,4,5 as an interface type is some common contact work I want them to do later:
foreach (var srv in ISP.GetService<ISpecialService>())
{
serv.Startup();
}
Any ideas how to solve this?