Closed dazinator closed 10 months ago
This issue raises its head with AddLogging()
When AddLogging() is called on a parent:
services.AddLogging(builder =>
{
builder.AddProvider(loggerProvider);
builder.AddXUnit(OutputHelper, (options) =>
{
options.IncludeScopes = true;
});
});
AddLogging
calls TryAdd<ILoggerFactory, LoggerFactory>
- so an ILoggerFactory
singleton exists at parent level.
Later when configuring the child container, if you call AddLogging()
again, it won't add a duplicate registration because it has inherited the above service description from the parent.
I've made it so that when configuring the child container services, you can modify a copy of the parent services it will inherit, but even with this enable AddLogging() has an issue:
childServices.AddLogging(a =>
{
a.ClearProviders(); // removes all ILoggerProvider but does not remove the ILoggerFactory asusmable this is overriding that reg
a.AddProvider(loggerProvider); // this provider is singleton instance we want to inherit from parent.
a.AddXUnit(OutputHelper, (options) =>
{
options.IncludeScopes = true;
});
a.SetMinimumLevel(LogLevel.Warning);
});
When an ILogger<T>
is resolved from the child container (using singleton delegation), it seems to be delegated to the parent container, rather than coming from the child container.
Closing
When deriving a child container, The parent registrations are able to be resolved from the child container. Another way to phrase this is that: the child container inherits parent services.
However, suppose the parent container has
IHostedService
s registered. These are typically run as background services by theIHost
. Suppose we then derive a child container for anotherIHost
and start that running also. We end up with the same IHostedServices also being started by the new IHost so they are now running twice - once at the parent level and again at the child level.It would be good to allow certain services to be optionally "not inherited" by the child container.
I believe this could be done by filtering out the service type from the parent service collection that is used to build the child container.
Also (todo: move to seperate issue) when thinking about this scenario of essentially creating another
IHost
from an existing child container / IServiceProvider - how would that work in practice? Typically new hosts use startup classes - but I could supply an extension method to configure one from an existing or newly derived child container?