Home > Enterprise >  Register IStartupFilter with TryAddSingleton equivalent in ASP.NET Core
Register IStartupFilter with TryAddSingleton equivalent in ASP.NET Core

Time:04-14

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.

  • If I use AddSingleton then the service is added, but could be added multiple times.
  • If I use 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?

CodePudding user response:

you could add

services.RemoveAll<IStartupFilter>();

before your codes

also,you could try the method in ServiceCollectionDescriptorExtensions class:

public static IServiceCollection Replace(this IServiceCollection collection, ServiceDescriptor descriptor);

Result: enter image description here

CodePudding user response:

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.

  • Related