My class library registers an IStartupFilter
(using a factory) with the ASP.NET Core container:
services.AddSingleton<IStartupFilter>(serviceProvider =>
ActivatorUtilities.CreateInstance<MyStartupFilter>(serviceProvider, new object[] { arg1, arg2 }));
That works.
But there are multiple ways to register the class library, so I don't want the filter to be added multiple times.
AddSingleton
then the service is added, but could be added multiple times.TryAddSingleton
then the service is not added at all - because the runtime already registers an IStartupFilter
of its own (HostFilteringStartupFilter
)How can I "try add" a startup filter that uses a factory?
Here's a dirty way to do it. If there's a better way please post your answer and I'll accept it.
var alreadyRegistered = services.Any(sd =>
sd.ServiceType == typeof(IStartupFilter) &&
sd.ImplementationFactory?.Target?.GetType() == this.GetType()
);
if (!alreadyRegistered)
{
services.AddSingleton<IStartupFilter>(serviceProvider =>
ActivatorUtilities.CreateInstance<MyStartupFilter>(serviceProvider, new object[] { arg1, arg2 }));
}
This fiddles with the service collection, which is an implementation detail of the container that should be left alone. And it assumes that the check and the registration occur in the same class. And it does not actually specify MyStartupFilter
, so you're not even sure it's doing the right thing, especially if that class adds other startup filters.
Dirty but works in simple cases.