Search code examples
c#asp.net-core-mvcsimple-injector

How to register IViewComponentDescriptorProvider in .NET Core?


I have set up my dependency injection using SimpleInjector in the same way as presented here. Unfortunately, calling RegisterMvcViewComponents on the container object throws an exception:

No service for type 'Microsoft.AspNetCore.Mvc.ViewComponents.IViewComponentDescriptorProvider' has been registered.

Does the container have a corresponding method for registering the provider? Or should it be done in some other way?

The code:

public class Startup
{
    private Container _container = new Container();

    public void ConfigureServices(IServiceCollection services)
    {
        services.InitializeTestData();

        services.AddMvcCore();

        services.AddSingleton<IControllerActivator>(new SimpleInjectorControllerActivator(_container));
        services.AddSingleton<IViewComponentActivator>(new SimpleInjectorViewComponentActivator(_container));           
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseSimpleInjectorAspNetRequestScoping(_container);
        _container.Options.DefaultScopedLifestyle = new AspNetRequestLifestyle();
        InitializeContainer(app);
        _container.Verify();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "Default",
                template: "{controller=Home}/{action=Index}/{id?}"
            );
        });
    }

    private void InitializeContainer(IApplicationBuilder app)
    {
        _container.RegisterMvcControllers(app);
        _container.RegisterMvcViewComponents(app);

        _container.Register<IDbContext>(() => new DbContext("GuitarProject"));
        _container.Register<IJournalEntryRepository, JournalEntryRepository>();
    }
}

Stack trace (the type of exception is InvalidOperationException):

at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at SimpleInjector.SimpleInjectorAspNetCoreMvcIntegrationExtensions.RegisterMvcViewComponents(Container container, IApplicationBuilder applicationBuilder) at ProjectX.Startup.InitializeContainer(IApplicationBuilder app)


Solution

  • Change the following line:

    services.AddMvcCore();
    

    To:

    services.AddMvc();
    

    Simple Injector's RegisterMvcViewComponent method requires the IViewComponentDescriptorProvider abstraction to be registered in the ASP.NET Core configuration system. The extension method uses the IViewComponentDescriptorProvider to find out which view components it needs to register. The AddMvcCore() extension method you are calling however, does not register this IViewComponentDescriptorProvider, since the AddMvcCore method only registers some basic functionality; it omits view specific stuff. The AddMvc() extension method on the other hand, initializes the whole package including view related stuff such as the IViewComponentDescriptorProvider.

    If you're not interested in view components, you can also omit the call to RegisterMvcViewComponents().