Невозможно разрешить экземпляр в Webapp program.cs в C# .NET Core.C#

Место общения программистов C#
Ответить
Гость
 Невозможно разрешить экземпляр в Webapp program.cs в C# .NET Core.

Сообщение Гость »


У меня 4 проекта на C#
[*]WebApp (веб-приложение ASP.NET Core MVC) [*]EmailNotificationService (библиотека классов) [*]PushNotificationService (библиотека классов) [*]EventBroker (библиотека классов)
В веб-приложении у меня работает фоновая служба, которая постоянно прослушивает очередь (внедренную как синглтон). Очередь обновляется веб-приложением, а фоновая служба считывает из очереди и обрабатывает каждый элемент, а затем загружает его в базу данных. Фоновая служба также содержит экземпляр EventManager (внедренный в синглтон), с помощью которого она публикует событие загрузки

публичный класс UploadBackgroundService: BackgroundService { частный UploadQueue _workerQueue только для чтения; частный только для чтения IServiceProvider _serviceProvider; частный только для чтения ILogger _logger; частный только для чтения EventManager _eventManager; общедоступная UploadBackgroundService (UploadQueue workerQueue, IServiceProvider serviceProvider, ILogger регистратор, EventManager eventManager) { _workerQueue = workerQueue ?? бросить новое ArgumentNullException(nameof(workerQueue)); _serviceProvider = поставщик услуг ?? выдать новое ArgumentNullException(nameof(serviceProvider)); _eventManager = eventManager ?? бросить новое ArgumentNullException(nameof(eventManager)); _logger = регистратор; } защищенное переопределение асинхронной задачи ExecuteAsync (CancellationToken StopToken) { в то время как (!stoppingToken.IsCancellationRequested) { пытаться { использование области IServiceScope = _serviceProvider.CreateScope(); используя DbContext dbContext =scope.ServiceProvider.GetService() ?? throw new Exception("Контекст базы данных имеет значение null!"); await foreach(Func workItem в this._workerQueue.ReadAsyncStream()) { UploadResult uploadResult = ждут workItem (dbContext); _eventManager.NotifyObservers(новый UploadResult(Enums.UploadStatus.Error)); } } поймать (Исключение ex) { Console.WriteLine(ex.ToString()); } } } } Проект EventBroker содержит класс EventManager, который создает событие загрузки и уведомляет всех своих подписчиков.

публичный класс EventManager { публичное событие EventHandler? ЗагрузитьСобытие; общедоступная виртуальная пустота OnUpload (UploadEventArgs uploadEventArgs) { UploadEvent?.Invoke(this, uploadEventArgs); } public void NotifyObservers (объект uploadResult) { UploadEventArgs uploadEventArgs = новый UploadEventArgs(); uploadEventArgs.Data = JsonConvert.SerializeObject(uploadResult); OnUpload (uploadEventArgs); } } EmailNotificationsService содержит класс потребителя электронной почты, который подписывается на событие загрузки в EventManager и при каждом получении уведомления отправляет электронное письмо пользователям.

публичный класс EmailConsumer: IConsumer { частный только для чтения IEmailSender _emailSender; общедоступный EmailConsumer (IEmailSender emailSender) { _emailSender = emailSender ?? выбросить новое ArgumentNullException(nameof(emailSender)); } публичная недействительная подписка (EventManager eventBroker) { eventBroker.UploadEvent += SendEmailNotifications!; } public void SendEmailNotifications (отправитель объекта, UploadEventArgs eventArgs) { EmailUploadResult uploadResult = JsonConvert.DeserializeObject(eventArgs.Data) ?? выдать новое InvalidDataException("Поврежденные данные"); _emailSender.SendEmailAsync(null, new List {new Address("testcapsdev@outlook.com") }, null, null, null, uploadResult); } } PushNotificationsService содержит потребительский класс signalRNotification, который подписывается на событие загрузки в EventManager и при каждом получении уведомления отправляет push-уведомления в пользовательский интерфейс.

публичный класс SignalRNotificationConsumer: IConsumer { частный только для чтения IHubContext _hubContext; public SignalRNotificationConsumer (IHubContexthubContext) { _hubContext = HubContext; } публичная недействительная подписка (EventManager eventBroker) { eventBroker.UploadEvent += SendSignalRNotifications!; } Private void SendSignalRNotifications (отправитель объекта, UploadEventArgs uploadEventArgs) { пытаться { SignalRUploadResult uploadResult = JsonConvert.DeserializeObject(uploadEventArgs.Data) ?? выдать новое InvalidDataException("Поврежденные данные"); _hubContext.Clients.All.UploadNotifications(uploadResult); } поймать (исключение ex) { Console.WriteLine(ex); } } } Теперь я подписываюсь на событие внутри веб-приложения program.cs:

var Services = builder.Services; Services.AddSingleton(); Services.AddSingleton(); Services.AddScoped().AddScoped(s => s.GetService()!); Services.AddScoped().AddScoped(s => s.GetService()!); Services.AddScoped(); вар приложение = builder.Build(); EventManager eventBroker = app.ServiceProvider.GetService()!; IConsumer потребитель = (IConsumer)app.ServiceProvider.GetService(typeof(EmailConsumer))!; потребитель.Подписаться(eventBroker); IConsumer потребитель = (IConsumer)app.ServiceProvider.GetService(typeof(SignalRNotificationConsumer))!; потребитель.Подписаться(eventBroker); Теперь я получаю сообщение об ошибке

Невозможно разрешить службу с ограниченной областью действия от корневого поставщика

Я не хочу подписываться на фоновую службу, которая работает нормально. Потому что фоновой службе ничего не нужно знать о подписчиках.

защищенное переопределение асинхронной задачи ExecuteAsync (CancellationToken StoppingToken) { IConsumer signalRConsumer = (IConsumer)_serviceProvider.CreateScope().ServiceProvider.GetService(typeof(SignalRNotificationConsumer))! ?? выдать новое ArgumentNullException("SignalRConsumer"); IConsumer emailConsumer = (IConsumer)_serviceProvider.CreateScope().ServiceProvider.GetService(typeof(EmailConsumer))! ?? выдать новое ArgumentNullException("SignalRConsumer"); signalRConsumer.Subscribe(_eventManager); emailConsumer.Subscribe(_eventManager); в то время как (!stoppingToken.IsCancellationRequested) { пытаться { использование области IServiceScope = _serviceProvider.CreateScope(); используя DbContext dbContext =scope.ServiceProvider.GetService() ?? throw new Exception("Контекст базы данных имеет значение null!"); await foreach(Func workItem в this._workerQueue.ReadAsyncStream()) { UploadResult uploadResult = ждут workItem (dbContext); _eventManager.NotifyObservers(новый UploadResult(Enums.UploadStatus.Error)); } } поймать (Исключение ex) { Console.WriteLine(ex.ToString()); } } } Приведенный выше код работает нормально.

Итак, может кто-нибудь указать правильное направление. Уместна ли моя мысль? и как мне заставить это работать без инициализации подписчиков фоновой службой.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»