【问题标题】:Blazor How to fix IMediator InvalidOperationException Cannot resolve from root provider because it requires scoped service IDbContextBlazor 如何修复 IMediator InvalidOperationException 无法从根提供程序解析,因为它需要范围服务 IDbContext
【发布时间】:2021-10-11 16:00:06
【问题描述】:

我创建了一个应用程序程序集,我引用了一个 REST-Api 和 Blazor 应用程序。 REST-Api 工作正常,但 Blazor 应用程序给出以下错误:

InvalidOperationException:无法解决 'MediatR.IRequestHandler`2[Application.Customers.Queries.GetCustomersList.GetCustomersListQuery,Application.Common.Viewmodels.CustomerListVm]' 来自根提供商,因为它需要范围服务 'Application.Common.Interfaces.IWegisterDbContext'。 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(类型 serviceType, IServiceScope 范围, IServiceScope rootScope)

InvalidOperationException:为请求构造处理程序时出错 类型 MediatR.IRequestHandler`2[Application.Customers.Queries.GetCustomersList.GetCustomersListQuery,Application.Common.Viewmodels.CustomerListVm]。 向容器注册您的处理程序。查看 GitHub 中的示例 举些例子。 MediatR.Internal.RequestHandlerBase.GetHandler(ServiceFactory 工厂)

在下面的代码示例中,我放置了我的 Starup 文件,两个项目都在同一个解决方案中,引用相同的项目。 我已经尝试添加授权,但这显然不起作用。我不知道问题出在哪里,是我遗漏了什么还是这个 Blazor? 两个程序集中的 MediatR 版本相同。

这是我从 REST-Api 启动的:

using Application;
using Application.Common.Interfaces;
using Infrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Persistence;
using WebApi.Services;

namespace Wegister.WebApi
{
    public class Startup
    {
        public IWebHostEnvironment Environment { get; }
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        {
            Configuration = configuration;
            Environment = environment;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddPersistence(Configuration);
            services.AddInfrastructure();
            services.AddApplication();

            if (Environment.IsDevelopment())
            {
                services.AddScoped<ICurrentUserService, CurrentUserServiceDev>();
            }

            services.AddAuthorization(x =>
            {
                if (Environment.IsDevelopment())
                    x.DefaultPolicy = new AuthorizationPolicyBuilder()
                    .RequireAssertion(_ => true)
                    .Build();
            });

            services.AddControllers().AddNewtonsoftJson(options =>
                options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            );
        }

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

            app.UseHttpsRedirection();
            app.UseHsts();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

这是我在 Blazor 应用程序中的启动:

using Application;
using Application.Common.Interfaces;
using Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Persistence;
using WebUI.Services;

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<SessionService>();
            services.AddSingleton<WorkHourService>();
            services.AddSingleton<ItemService>();
            services.AddSingleton<CustomerService>();

            services.AddPersistence(Configuration);
            services.AddInfrastructure();
            services.AddApplication();

            services.AddRazorPages();
            services.AddServerSideBlazor();

            services.AddScoped<ICurrentUserService, CurrentUserServiceDev>();
        }

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

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

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }
    }
}

AddApplication依赖注入方法如下:

public static IServiceCollection AddApplication(this IServiceCollection services)
        {
            services.AddScoped<IRequestHandler<GetCustomersListQuery, CustomerListVm>, GetCustomersListQueryHandler>();
            services.AddMediatR(Assembly.GetExecutingAssembly());

            services.AddTransient<ICustomerFactory, CustomerFactory>();

            return services;
        }

添加持久性:

public static IServiceCollection AddPersistence(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddDbContext<WegisterDbContext>(options =>
                options.UseSqlServer(configuration.GetConnectionString("WegisterDbConnectionString")));

            services.AddScoped<IWegisterDbContext>(provider => provider.GetService<WegisterDbContext>());

            return services;
        }

基础设施:

public static IServiceCollection AddInfrastructure(this IServiceCollection services)
        {
            services.AddTransient<IDateTime, MachineDateTime>();
            services.AddTransient<INotificationService, NotificationService>();

            return services;
        }

【问题讨论】:

  • 尝试删除services.AddScoped&lt;IRequestHandler&lt;GetCustomersListQuery, CustomerListVm&gt;, GetCustomersListQueryHandler&gt;();添加services.AddMediatR(Assembly.GetExecutingAssembly())就足够了。

标签: c# asp.net-core dependency-injection blazor mediatr


【解决方案1】:

不幸的是,“注册您的处理程序”可能有许多不同的原因(正如我自己发现的那样)。你会想读 this SO article on the matter。当您的数据库上下文位于不同的程序集中时,我将您直接链接到对我来说是最终修复的那个。但这只是在我修复了文章中提到的其他几个问题之后的问题。

总结一下:

  1. 告诉serviceprovider 不要验证 CreateHostBuilder 中的范围。 (Thanks Sarah Akbari)
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    }).UseDefaultServiceProvider(options =>
    options.ValidateScopes = false); // needed for mediatr DI
  1. 确保您的存储库在那里:
    services.AddScoped<IRepo1, Repo1>();
  1. 在添加您的存储库后添加 MediatR,并为您拥有处理程序的每个程序集提供程序集,如下所示:
    var assembly = AppDomain.CurrentDomain.Load("HandlersDomain");
    var assembly2 = AppDomain.CurrentDomain.Load("HandlersDomain2");
    services.AddMediatR(assembly, assembly);

按照这个食谱,你真的应该是 gtg。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-22
    • 2022-10-18
    • 2020-08-01
    • 2018-04-04
    • 1970-01-01
    • 2020-09-06
    • 2018-09-27
    • 2020-05-11
    相关资源
    最近更新 更多