Menelaos Vergis Menelaos Vergis - 8 months ago 71
C# Question

Registration of ITagHelperActivator at Simple Injector in ASP.NET Core MVC app

I want to resolve some dependencies at a

and I have read here that I must register the

I tried that with the following code:

services.AddSingleton<ITagHelperActivator>(new SimpleInjectorTagHelperActivator(container));

But I get the following error:

ActivationException: The constructor of type UrlResolutionTagHelper
contains the parameter with name 'urlHelperFactory' and type
IUrlHelperFactory that is not registered. Please ensure
IUrlHelperFactory is registered, or change the constructor of

When I register
then an other dependency is missing and I get an error for that too.

I guess I am doing something wrong, I don't want to register the complete framework.

Answer Source

This won't work. By replacing the default tag helper activator, you redirected the resolution of all tag helpers to Simple Injector, but apparently, there are built-in tag helpers and they require the built-in container to be resolved.

You should register a tag helper activator that resolves only application components and forwards all other requests back to the built-in DefaultTagHelperActivator. Example:

public class MultipleTagHelperActivator : ITagHelperActivator
    private readonly Container container;
    private readonly ITagHelperActivator frameworkActivator;
    private readonly Predicate<Type> useSimpleInjector;

    public MultipleTagHelperActivator(Container container,
        ITagHelperActivator frameworkActivator, Predicate<Type> useSimpleInjector)
        this.container = container;
        this.frameworkActivator = frameworkActivator;
        this.useSimpleInjector = useSimpleInjector;

    public TTagHelper Create<TTagHelper>(ViewContext context) 
        where TTagHelper : ITagHelper =>
            ? (TTagHelper)this.container.GetInstance(typeof(TTagHelper))
            : this.frameworkActivator.Create<TTagHelper>(context);

This is however where it gets really smelly with ASP.NET Core. While previous versions of ASP.NET made it super simple to wrap an original type with a new type (decoration), this same practice has become really painful in ASP.NET Core. I reported this issue a long time ago.

But long story short, you can add your custom activator as follows:

public void ConfigureServices(IServiceCollection services)
    // Add framework services.

    // NOTE: Make this registration AFTER the call to AddMvc
    services.AddSingleton<ITagHelperActivator>(provider =>
        new MultipleTagHelperActivator(
            new DefaultTagHelperActivator(provider.GetService<ITypeActivatorCache>()),
            useSimpleInjector: type => type.Namespace.StartsWith("MyApplication")));

    // rest of your configuration