simpleinjector / SimpleInjector

An easy, flexible, and fast Dependency Injection library that promotes best practice to steer developers towards the pit of success.
https://simpleinjector.org
MIT License
1.21k stars 154 forks source link

How to register IClientRequestParametersProvider? #687

Closed moustaphastar closed 5 years ago

moustaphastar commented 5 years ago

While using simple injector on an asp net core 3 react template application ( asp .net core 3 + entity framework 3 + react ), i have trouble with registering IClientRequestParametersProvider type and get the following error:

System.InvalidOperationException: 'The configuration is invalid. Creating the instance for type OidcConfigurationController failed. The constructor of type OidcConfigurationController contains the parameter with name 'clientRequestParametersProvider' and type IClientRequestParametersProvider that is not registered. Please ensure IClientRequestParametersProvider is registered, or change the constructor of OidcConfigurationController.' ActivationException: The constructor of type OidcConfigurationController contains the parameter with name 'clientRequestParametersProvider' and type IClientRequestParametersProvider that is not registered. Please ensure IClientRequestParametersProvider is registered, or change the constructor of OidcConfigurationController.

Here is the controller class:

public class OidcConfigurationController : Controller
{
    public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider)
    {
        ClientRequestParametersProvider = clientRequestParametersProvider;
    }

    public IClientRequestParametersProvider ClientRequestParametersProvider { get; }

    [HttpGet("_configuration/{clientId}")]
    public IActionResult GetClientRequestParameters([FromRoute]string clientId)
    {
        var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId);
        return Ok(parameters);
    }
}

And my Startup.cs file with simple injector configuration:

using Microsoft.Extensions.DependencyInjection;
using SimpleInjector;
using SimpleInjector.Lifestyles;
using Microsoft.AspNetCore.Mvc.Controllers;
using SimpleInjector.Integration.AspNetCore.Mvc;
...
using Microsoft.AspNetCore.ApiAuthorization.IdentityServer;

namespace App.FrontEnd
{
    public class Startup
    {
        private Container container = new Container();
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<ApplicationUser>()
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

            services.AddAuthentication()
                .AddIdentityServerJwt();
            services.AddMvc()
                .AddNewtonsoftJson();

            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/build";
            });

            // Simpleinjector implementation
            container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

            // Register services
            container.Register<DbContext>(() => {
                var optionsBuilder = new DbContextOptionsBuilder<AppDBContext>();
                optionsBuilder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
                return new AppDBContext(optionsBuilder.Options);
            });

            SimpleInjectorBootstraperRegister.BootstrapBussinessRegister(container);

            // Register controllers DI resolution
            services.AddSingleton<IControllerActivator>(new SimpleInjectorControllerActivator(container));

            // Wrap AspNet requests into Simpleinjector's scoped lifestyle
            services.UseSimpleInjectorAspNetRequestScoping(container);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseAuthentication();
            app.UseIdentityServer();

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

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });

            //Simpliinjector implementation
            container.RegisterMvcControllers(app);

            // Verify Simple Injector configuration
            container.Verify();
        }
    }
}
dotnetjunkie commented 5 years ago

Did you follow the ASP NET Core integration guidance? I'm missing the call to AutoCrossWireAspNetComponents from your configuration.

moustaphastar commented 5 years ago

I red the Simple Injector ASP NET Core MVC Integration Guide and found that i was missing AutoCrossWireAspNetComponents part in my configuration as you pointed out. I changed my configuration in Startup.cs file by inserting following lines and it works now:

Thank you very much indeed.