aspnet / DependencyInjection

[Archived] Contains common DI abstractions that ASP.NET Core and Entity Framework Core use. Project moved to https://github.com/aspnet/Extensions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

.net core 2 InvalidOperationException: Cannot resolve scoped service 'IFillDataService' from root provider.

tarekgh opened this issue · comments

From @sadeqhatami on August 28, 2017 14:43

i use asp.net core 2 and VS 2017 15.3.2 and windows 10

i declare middleware and in .net core 1.1 it run without any error, but in .net core 2 i get this error

InvalidOperationException: Cannot resolve scoped service 'IFillDataService' from root provider.

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
           Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {

            services.AddSingleton(Configuration);
      
            services.AddScoped<IFillDataServiceService, FillDataServiceService>();

            services.Configure<GzipCompressionProviderOptions>
                (options => options.Level = CompressionLevel.Fastest);
            services.AddResponseCompression(options => { options.Providers.Add<GzipCompressionProvider>(); });

            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseDeveloperExceptionPage();
            app.UseStatusCodePages();

            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseFillDataService();
            app.UseResponseCompression();

            app.UseMvc();
        }
    }
  public static IApplicationBuilder UseFillDataService(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<UseFillDataServiceMiddleware>();
        }
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .ConfigureAppConfiguration((hostingContext, config) =>
            {
                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();
            })
          
                .Build();
    }

raw exception details

System.InvalidOperationException: Cannot resolve scoped service 'IFillDataService' from root provider.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, ServiceProvider serviceProvider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.<UseMiddleware>b__0(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

Copied from original issue: dotnet/corefx#23604

From @danmosemsft on August 28, 2017 17:40

@sadeqhatami can you please move this issue to https://github.com/aspnet/DependencyInjection ?

From @jrmitch120 on August 28, 2017 23:58

Is your IFillDataService dependency defined on the Invoke? If not, try moving it there.

From @sadeqhatami on August 29, 2017 4:45

@jrmitch120 yes, i defined Invoke,

From @sadeqhatami on August 29, 2017 4:48

according to this link
i use

.UseDefaultServiceProvider(options => 
           options.ValidateScopes = false)

and started to workvery well
but i dont why...!
can help any body about that ?

From @jrmitch120 on August 29, 2017 5:22

Can you post the code to your UseFillDataServiceMiddleware?

From @sadeqhatami on August 29, 2017 5:52

@jrmitch120

public class UseFillDataServiceMiddleware
    {
        private readonly RequestDelegate _next;
    
        private readonly IFillDataServiceService _fillDataService;

        private readonly bool _serviceIsActive;

        public UseFillDataServiceMiddleware(RequestDelegate next, IFillDataServiceService fillDataService, IConfiguration configuration)
        {
            _fillDataService = fillDataService;
            _serviceIsActive = configuration.GetValue<bool>("Service:IsActive");
            _next = next;
        }

        public Task Invoke(HttpContext context)
        {
           
            /* .. some code for read data*/

            return this._next(context);
        }
    }

From @jrmitch120 on August 29, 2017 6:7

You should move non-singleton dependencies to the invoke method. Also, make the method async and await the _next.Invoke.

public async Task Invoke(HttpContext context, IFillDataServiceService fillDataService)
{
   /* Code */

   await _next(context);
}

Yeah I think this is exactly what @tarekgh has said.

If a middleware component takes in constructor arguments they must be singleton-lifetime.

If a middleware components takes in Invoke method arguments they can be singleton-lifetime or scoped-lifetime.

@pakrym - can you confirm?

Yes this is how it works. This isn't a DI issue either. You can implement the new IMiddleware interface introduced in 2.0 to get the scoped behavior (activated once per request)

Just to mention I am not the one commented on the issue. I just copied it from corefx repo https://github.com/dotnet/corefx/issues/23604.

Oops sorry it was indeed @jrmitch120 who made the comment.

Anyway, closing the issue because the issue was solved. Thanks!