I have a backend service that has its own scoped context. This service polls external appliances every minute and runs on a minute timer to repeat the process. Every minute, the service also checks for appliance state changes (start, stop, run, off) which need to be applied. These state changes, if any, will have come from a Razor Page server Post method using the DBcontext and DI to update the DeployedAppliance in the DB.
The issue is as follows: the Razor Page successfully updates the DeployedAppliance DB (state enum). However, the backend service scope, created anew every minute, is not getting the new DeployedAppliance state.
Here is some relevant backend code:
public class ApplianceService : IHostedService, IDisposable
{
private Timer _timer;
private readonly IServiceScopeFactory _serviceScopeFactory;
private IApplianceManager applianceMgr;
public Task StartAsync(CancellationToken stoppingToken)
{
applianceMgr = new ApplianceManagerImpl();
...
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
}
private void DoWork(object state)
{
// Create local scope.
using (var scope = _serviceScopeFactory.CreateScope())
{
var _db = scope.ServiceProvider.GetRequiredService<DbContext>();
applianceMgr.Db = _db;
applianceMgr.DoRemoteAppliancePolling();
applianceMgr.CheckForApplianceStateChange();
}
}
}
public class ApplianceManager : IApplianceManager
{
DeployedAppliance DeployedAppliance {get; set;}
...
public void CheckForApplianceStateChange()
{
// This DeployedAppliance object never gets the change in state that is actually in the Db
DeployedAppliance = Db.DeployedAppliances.Find(ApplianceDeploymentID);
...
}
}
I have looked at stackoverflow submissions to refresh Db entities. I have tried the following code to refresh the Db.
// refresh DBcontext
var context = ((IObjectContextAdapter)Db).ObjectContext;
var refreshableObjects = Db.ChangeTracker.Entries().Select(c => c.Entity).ToList();
context.Refresh(RefreshMode.StoreWins, refreshableObjects);
Howevever, this code throws: InvalidCastException: Unable to cast object of type 'Pilot.Models.Database.DbContext' to type 'System.Data.Entity.Infrastructure.IObjectContextAdapter'. Note that the DbContext inherits from IdentityDbContext.