Hi, I wanted to update real time total number of notifications besides a badge. Badge and the number object are in top menu of _Layout.cshtml.
<li class="nav-item dropdown"> <a class="nav-link" data-toggle="dropdown" href="#" style="width:66px">
@*
The "noticeCount" will be updated from real time
*@
<i class="fa fa-bell-o notification">
<span id="noticeCount" class="badge badge-warning navbar-badge"> </span>
</i>
</a>
...
I also defined a js function in _Layout.cshtml for JsRuntime to call
<script>
window.updateNoticeNumber = (noticeInt) => {
noticeCount.innerText = noticeInt;
};
</script>
My background service
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.JSInterop;
using MyDataLibrary.DataServices;
namespace MyNamespace
{
public class LongRunningWorker : BackgroundService
{
private readonly ICounter _counter;
private readonly INoticeCount _noticecounter;
private readonly JSRuntime _jsfunc;
public LongRunningWorker(ICounter counter, INoticeCount noticeCount, JSRuntime jsfunc )
{
_counter = counter ?? throw new ArgumentNullException(nameof(counter));
_noticecounter = noticeCount ?? throw new ArgumentNullException(nameof(noticeCount));
_jsfunc = jsfunc;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
return Task.Run(async () =>
{
while (!stoppingToken.IsCancellationRequested)
{
long _noticecount = 0;
_counter.Increment();
_noticecounter.GetCounter(_noticecount);
await _jsfunc.InvokeAsync<string>("updateNoticeNumber", _noticecount.ToString().Trim());
await Task.Delay(500);
}
});
}
}
}
When I try to run the application, I got the following error.
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: Mynamespace.LongRunningWorker': Unable to resolve service for type 'Microsoft.JSInterop.JSRuntime' while attempting to activate 'Mynamespace.LongRunningWorker'.)'
What I have tried:
I had also tried to create an code interface for JsRuntime and registered it in Startup.cs
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using T20DataLibrary.DataModels;
using T20DataLibrary.DataServices;
namespace AspNetMaker2020
{
public class JsInteropClasses : IJsInteropClasses
{
private readonly IJSRuntime _jsRuntime;
public JsInteropClasses(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public async Task updateCounter(long _count)
{
await _jsRuntime.InvokeAsync<string>("updateNoticeNumber", _count.ToString().Trim(), _count.ToString().Trim() + " new notifications");
}
}
}
services.AddSingleton<IJsInteropClasses, JsInteropClasses>();
services.AddHostedService<LongRunningWorker>();
And modified "LongRunningWorker" to the following
private readonly IJSRuntime _jsfunc;
However, I ended up another type error,
InvalidOperationException: Error while validating the service descriptor 'ServiceType: MyNamespace.IJsInteropClasses Lifetime: Singleton ImplementationType: MyNamespace.JsInteropClasses': Cannot consume scoped service 'Microsoft.JSInterop.IJSRuntime' from singleton 'MyNamespace.IJsInteropClasses'.
Can anyone advice how to overcome this issue?
Thanks in advance
Wilson