Обновлять
Я изменил автозагрузку на:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Actio.Api.Handlers;
using Actio.Api.Repositories;
using Actio.Common.Auth;
using Actio.Common.Events;
using Actio.Common.Mongo;
using Actio.Common.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Actio.Api
{
public class Startup
{
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.AddMvc();
services.AddJwt(Configuration);
services.AddRabbitMq(Configuration);
services.AddMongoDB(Configuration);
services.AddScoped<IEventHandler<ActivityCreated>, ActivityCreatedHandler>();
services.AddScoped<IActivityRepository, ActivityRepository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// app.ApplicationServices.GetService<IDatabaseInitializer>().InitializeAsync();
using (var serviceScope = app.ApplicationServices.CreateScope())
{
serviceScope.ServiceProvider.GetService<IDatabaseInitializer>().InitializeAsync();
}
app.UseAuthentication();
app.UseMvc();
}
}
}
Но теперь у меня ошибка в SubscribeToEvent: Не удается разрешить службу с заданной областью
'Actio.Common.Events.IEventHandler`1[Actio.Common.Events.ActivityCreated]' from root provider.'
в моем ServiceHost.cs.
ServiceHost.cs
using System;
using Actio.Common.Commands;
using Actio.Common.Events;
using Actio.Common.RabbitMq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using RawRabbit;
namespace Actio.Common.Services
{
public class ServiceHost : IServiceHost
{
private readonly IWebHost _webHost;
public ServiceHost(IWebHost webHost)
{
_webHost = webHost;
}
public void Run() => _webHost.Run();
public static HostBuilder Create<TStartup>(string[] args) where TStartup : class
{
Console.Title = typeof(TStartup).Namespace;
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
var webHostBuilder = WebHost.CreateDefaultBuilder(args)
.UseConfiguration(config)
.UseStartup<TStartup>();
return new HostBuilder(webHostBuilder.Build());
}
public abstract class BuilderBase
{
public abstract ServiceHost Build();
}
public class HostBuilder : BuilderBase
{
private readonly IWebHost _webHost;
private IBusClient _bus;
public HostBuilder(IWebHost webHost)
{
_webHost = webHost;
}
public BusBuilder UseRabbitMq()
{
_bus = (IBusClient)_webHost.Services.GetService(typeof(IBusClient));
return new BusBuilder(_webHost, _bus);
}
public override ServiceHost Build()
{
return new ServiceHost(_webHost);
}
}
public class BusBuilder : BuilderBase
{
private readonly IWebHost _webHost;
private IBusClient _bus;
public BusBuilder(IWebHost webHost, IBusClient bus)
{
_webHost = webHost;
_bus = bus;
}
public BusBuilder SubscribeToCommand<TCommand>() where TCommand : ICommand
{
var handler = (ICommandHandler<TCommand>)_webHost.Services
.GetService(typeof(ICommandHandler<TCommand>));
_bus.WithCommandHandlerAsync(handler);
return this;
}
public BusBuilder SubscribeToEvent<TEvent>() where TEvent : IEvent
{
var handler = (IEventHandler<TEvent>)_webHost.Services
.GetService(typeof(IEventHandler<TEvent>));
_bus.WithEventHandlerAsync(handler);
return this;
}
public override ServiceHost Build()
{
return new ServiceHost(_webHost);
}
}
}
}
Недавно я начал изучать микросервисы с RabbitMQ. После долгой борьбы я получил образец кода, но я не могу его запустить, так как он выдает ошибку :"System.InvalidOperationException: 'Cannot resolve scoped service 'Actio.Common.Mongo.IDatabaseInitializer' from root provider.'".
Я хочу понять этот код, чтобы лучше понимать микросервисы.
Код-Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Actio.Api.Handlers;
using Actio.Api.Repositories;
using Actio.Common.Auth;
using Actio.Common.Events;
using Actio.Common.Mongo;
using Actio.Common.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Actio.Api
{
public class Startup
{
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.AddMvc();
services.AddJwt(Configuration);
services.AddRabbitMq(Configuration);
services.AddMongoDB(Configuration);
services.AddScoped<IEventHandler<ActivityCreated>, ActivityCreatedHandler>();
services.AddScoped<IActivityRepository, ActivityRepository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//Giving Error in below line
app.ApplicationServices.GetService<IDatabaseInitializer>().InitializeAsync();
app.UseAuthentication();
app.UseMvc();
}
}
}
Может ли кто-нибудь помочь, чтобы я мог отлаживать и лучше понимать.
Спасибо
да. 'using System.Threading.Tasks; пространство имен Actio.Common.Mongo {открытый интерфейс IDatabaseInitializer {Task InitializeAsync (); }}





Приведенная ниже ошибка пытается сообщить вам, что вы регистрируете IDatabaseInitializer как ограниченный сервис, но пытаетесь получить к нему доступ за пределами сфера:
"System.InvalidOperationException: 'Cannot resolve scoped service 'Actio.Common.Mongo.IDatabaseInitializer' from root provider.'"
Попробуйте создать область действия, а затем использовать такую службу, как:
using (var serviceScope = app.ApplicationServices.CreateScope())
{
serviceScope.ServiceProvider.GetService<IDatabaseInitializer>().InitializeAsync();
}
Спасибо. Я изменил, но опять ошибка в методе SubscribeToEvent. Любая помощь
Решение - отключить проверку области.
Итак, в файле src \ actio.common \ services \ servicehost.cs между строками 31-32 добавьте следующее:
.UseDefaultServiceProvider(options => options.ValidateScopes = false)
Другой альтернативный подход к решению проблемы - это переход с services.AddScoped на services.AddSingleton в program.cs, работа с синглтоном также позволит избежать проверки всей области видимости.
Вы настроили IDatabaseInitializer в своем DI?