ServiceType / generic TService appears to be combined with RegistrationStrategy expansion, rather than limiting the registration to the specified service type.
The documentation/comment says:
ServiceType - "The type of the service. If not set, the Registration property used to determine what is registered."
I interpreted this as: when ServiceType or <TService> is specified, only that service type should be registered; otherwise Registration determines whether to register self, implemented interfaces, etc.
However, with SelfWithProxyFactory, Injectio also registers all implemented interfaces and self, even when a generic service type is explicitly specified.
Reproduction
public interface IPrimaryService { }
public interface IStartupInitializer { }
[RegisterSingleton<IPrimaryService>(
Registration = RegistrationStrategy.SelfWithProxyFactory,
Duplicate = DuplicateStrategy.Skip)]
[RegisterSingleton<IStartupInitializer>(
Registration = RegistrationStrategy.SelfWithProxyFactory,
Duplicate = DuplicateStrategy.Append)]
internal sealed class MyService : IPrimaryService, IStartupInitializer, IAsyncDisposable
{
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}
Actual generated behavior
The first attribute generates registrations for:
IPrimaryService
IStartupInitializer
IAsyncDisposable
MyService
The second attribute also generates registrations for:
IStartupInitializer
IPrimaryService
IAsyncDisposable
MyService
Because the second attribute uses DuplicateStrategy.Append, it appends all of those registrations, not only IStartupInitializer.
This also causes unrelated implemented interfaces such as IAsyncDisposable to be registered as services.
Expected behavior
I expected the explicit generic service type to constrain the registration.
For example:
[RegisterSingleton<IPrimaryService>(
Registration = RegistrationStrategy.SelfWithProxyFactory)]
would register something equivalent to:
services.TryAddSingleton<MyService>();
services.TryAddSingleton<IPrimaryService>(
sp => sp.GetRequiredService<MyService>());
but would not also register every implemented interface.
Similarly:
[RegisterSingleton<IStartupInitializer>(
Registration = RegistrationStrategy.SelfWithProxyFactory,
Duplicate = DuplicateStrategy.Append)]
would append only IStartupInitializer, not IPrimaryService, IAsyncDisposable, and MyService.
Question
Is the current behavior intentional?
If it is intentional, the documentation/comment for ServiceType may be misleading because Registration is still used to expand additional service types even when ServiceType / TService is explicitly set.
If it is not intentional, this may be a generator bug in how explicit service types interact with RegistrationStrategy.SelfWithProxyFactory.
Version
Injectio version: 6.0.0
ServiceType / generic TService appears to be combined with RegistrationStrategy expansion, rather than limiting the registration to the specified service type.
The documentation/comment says:
I interpreted this as: when
ServiceTypeor<TService>is specified, only that service type should be registered; otherwise Registration determines whether to register self, implemented interfaces, etc.However, with
SelfWithProxyFactory, Injectio also registers all implemented interfaces and self, even when a generic service type is explicitly specified.Reproduction
Actual generated behavior
The first attribute generates registrations for:
IPrimaryServiceIStartupInitializerIAsyncDisposableMyServiceThe second attribute also generates registrations for:
IStartupInitializerIPrimaryServiceIAsyncDisposableMyServiceBecause the second attribute uses
DuplicateStrategy.Append, it appends all of those registrations, not onlyIStartupInitializer.This also causes unrelated implemented interfaces such as IAsyncDisposable to be registered as services.
Expected behavior
I expected the explicit generic service type to constrain the registration.
For example:
would register something equivalent to:
but would not also register every implemented interface.
Similarly:
would append only
IStartupInitializer, notIPrimaryService,IAsyncDisposable, andMyService.Question
Is the current behavior intentional?
If it is intentional, the documentation/comment for ServiceType may be misleading because Registration is still used to expand additional service types even when
ServiceType/TServiceis explicitly set.If it is not intentional, this may be a generator bug in how explicit service types interact with
RegistrationStrategy.SelfWithProxyFactory.Version
Injectio version: 6.0.0