0

I'm playing around with Dependency Injection and IOptions<T> pattern and found the following oddity that I would like to understand. Hope someone here can explain it.

So I have a .NET 7 WPF application to which I added from Nuget the following packages:

  1. CommunityToolkit.Mvvm version 8.0.0
  2. Microsoft.Extensions.Configuration version 7.0.0
  3. Microsoft.Extensions.Configuration.Json version 7.0.0
  4. Microsoft.Extensions.Options.ConfigurationExtensions version 7.0.0

In App.xaml.cs I configured the options:

var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
        .Build();
_serviceProvider = new ServiceCollection()
        .Configure<AppSettings>(configuration.GetSection(nameof(AppSettings)))
        .BuildServiceProvider();

My appSettings.json contains a single property:

{
  "AppSettings": {
    "IsUpdating": false
  }
}

And my AppSettings.cs has the proper class definition:

public partial class AppSettings : ObservableObject
{
    [ObservableProperty]
    private bool isUpdating;
}

So in my ViewModel class I inject IOptionsMonitor<AppSettings> and listen to changes:

public partial class ViewModel : ObservableObject
{
    [ObservableProperty]
    private AppSettings settings;

    public ViewModel(IOptionsMonitor<AppSettings> appSettings)
    {
         appSettings.OnChange<AppSettings>(SettingsChanged);
         settings = appSettings.CurrentValue;
    }

    private void SettingsChanged(AppSettings appSettings)
    {
         Settings.IsUpdating = appSettings.Updating;
    }
}

Now I place a breakpoint inside the SettingsChanged method and run the app.

I then open the appSettings.json file and change the value of IsUpdating. The first time I make a change, the breakpoint stops the code twice in a row - any further changes only stops once. If I close the app and start it again this reproduces 100% of the time - first change calls SettingsChanged twice, following changes to the file only calls it once.

So my first question is, what happens when it detects the first change I make that doesn't happen any other time after that until I restart the app?

I've also notice that it calls SettingsChanged even if I just saved the file without any change to it - shouldn't it only call it if a change was detected?

537mfb
  • 1,374
  • 1
  • 16
  • 32
  • The implementation uses FileSystemWatcher to detect changes of the File in the FileSystem. So a.) Its just watching the File and doesn't know if something in the file has actually changed. It would be a problem of the Monitor implementor to cache the previous content and then compare if actually changes had happen. Presumably while implementing nobody thought that that would be worth it. – Ralf Jan 27 '23 at 11:30
  • And b.) I said FileSystemWatcher so that you get the event twice is presumably an artifact of how the systems FileSystemWatcher works and makes it Platform dependent. The INotify stuff on Linux for example works differently and might behave differently here. c.) Conclusion just don't expect to get only one event for actual changes. Check yourself in the event if there was an actual change. – Ralf Jan 27 '23 at 11:31
  • Makes sense. The artifact thing if correct is a bunmer though. Care to put that as an answer @Ralf? – 537mfb Jan 27 '23 at 14:29
  • check this https://stackoverflow.com/q/1764809/810328 – vcRobe Mar 24 '23 at 17:54

0 Answers0