After learning about scoped/singleton/transient services here, I'm trying to understand why this code doesn't work. It's written in ASP.NET Core 2.
startup.cs
public void ConfigureServices(IServiceCollection services)
{
// ... other services
services.AddScoped<LiveData, LiveData>();
services.AddScoped<Utils, Utils>();
}
livedata.cs
public class LiveData
{
public LiveData() {
Plcs = new List<Plc>();
}
public List<Plc> Plcs { get; set; }
}
public class Plc
{
public string Name { get; set; }
public DateTime Datetime { get; set; }
public string OperatorName { get; set; }
}
utils.cs
public class Utils
{
private readonly LiveData _liveData;
public Utils(LiveData liveData)
{
_liveData = liveData;
// ... fill in _liveData.Plcs
}
public void SetOperatorName(string name, string operatorName)
{
Plc plc = _liveData.Plcs.SingleOrDefault(x => x.Name == name);
plc.OperatorName = operatorName;
}
}
testpage.chstml.cs
public class MachineDetailsModel : PageModel
{
private readonly LiveData _liveData;
private readonly Utils _utils;
public MachineDetailsModel(LiveData liveData, Utils utils)
{
_liveData = liveData;
_utils = utils;
}
public Plc Plc { get; set; }
public async Task<IActionResult> OnGetAsync(string id)
{
Plc = _liveData.Plcs.SingleOrDefault(x => x.Name == id);
return Page();
}
public IActionResult OnPostSetOperatorName(string name)
{
var operatorName = "foo";
_utils.SetOperatorName(name, operatorName);
Plc = _liveData.Plcs.SingleOrDefault(x => x.Name == name);
return RedirectToPage();
}
}
When the post handler is called, it correctly updates the OperatorName
fields. Before returning I checked the Plc
variable and it contains the new value "foo".
But when the page reloads (due to the post) and the Plc
variable is set again (note the two lines are the same) the OperatorName
is lost (null, as default).
As far as I understand the scoped services maintain the same instance for all requests in the same session (i.e. until I close the browser). Did I understand it wrong?