Red-Green-Code

Deliberate practice techniques for software developers

  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter

Time Tortoise: Settings, Part 2

By Duncan Smith Sep 16 0

Settings

This is one in a series of articles about Time Tortoise, a Universal Windows Platform app for planning and tracking your work schedule. For more on the development of this app and the ideas behind it, see my Time Tortoise category page.

Last week, I described the settings infrastructure that I’m building for Time Tortoise. This week: implementation details.

Settings and ISettings

One of my design goals for settings is that individual settings should be accessible as properties. For example, to retrieve the idle timeout setting, I could use this code:

if (duration.TotalSeconds >= _settings.IdleTimeoutSeconds)

The goal is for settings to be type-safe (not all strings), and visible to the programmer at design-time. Type _settings. in a C# file in Visual Studio, and all available settings are shown in a list.

_settings is of type ISettings, and it contains one property per setting. This does mean that when I add a new setting, I have to update the class and its interface. I can’t just add it to the settings text file and have it picked up automatically at runtime. But I don’t think that’s much of a disadvantage.

Since Settings implements an interface, unit tests can use mock settings. This allows each unit test to returns a custom value for each settings, based on the scenario being tested. No settings text file is necessary in this case.

SettingsUtility and ISettingsUtility

The SettingsUtility class takes care of reading from the settings text file, updating an instance of the Settings class, and exposing the Settings class as a property.

Reading the settings file using YamlDotNet is simple:

var input = File.ReadAllText(_settingsFileName);
var deserializer = new Deserializer();
Settings = deserializer.Deserialize<Settings>(input);

Line 1 reads a text file into a string. Line 2 creates the YAML deserializer. Line 3 deserializes the YAML string into the Settings object. Now we have an object full of settings.

The YAML format is as simple as a text file can be. If the Settings class has a property called IdleTimeoutSeconds, then this line in the YAML file will be deserialized into that property:

IdleTimeoutSeconds: 3

The string-to-integer conversion happens automatically.

Since SettingsUtility implements the ISettingsUtility interface, unit tests can provide a mock utility class that doesn’t actually read a text file from disk, and just exposes a mock Settings class with the appropriate settings values.

Notice that I haven’t mentioned any utility functions for updating settings. That’s because my text file UI design relies on a text editor to do the updates. That saves time on app UI that I can use for other features. And the target audience for this app is expected to be comfortable with a text editor. In my case, even as a user, I would rather edit settings in a text editor than fiddle with the app UI.

View Model Changes

Since SettingsUtility reads a file from disk, I decided the best place for it was in the Model. When a View Model class needs access to settings, it accepts a SettingsUtility instance in its constructor (the dependency injection pattern). This allows unit tests that are testing that view model class to mock the settings classes.

Once a view model has the settings dependency available, it can use it to retrieve the settings values that it needs.

(Image credit: Didriks)

Categories: TT

Prev
Next

Stay in the Know

I'm trying out the latest learning techniques on software development concepts, and writing about what works best. Sound interesting? Subscribe to my free newsletter to keep up to date. Learn More
Unsubscribing is easy, and I'll keep your email address private.

Getting Started

Are you new here? Check out my review posts for a tour of the archives:

  • Lessons from the 2020 LeetCode Monthly Challenges
  • 2019 in Review
  • Competitive Programming Frequently Asked Questions: 2018 In Review
  • What I Learned Working On Time Tortoise in 2017
  • 2016 in Review
  • 2015 in Review
  • 2015 Summer Review

Archives

Recent Posts

  • LeetCode 11: Container With Most Water February 24, 2021
  • LeetCode 47: Permutations II February 17, 2021
  • LeetCode 897: Increasing Order Search Tree February 10, 2021
  • LeetCode 394: Decode String February 3, 2021
  • LeetCode 1022: Sum of Root To Leaf Binary Numbers January 27, 2021
  • LeetCode 1288: Remove Covered Intervals January 20, 2021
  • LeetCode 227: Basic Calculator II January 13, 2021
  • A Project for 2021 January 6, 2021
  • Lessons from the 2020 LeetCode Monthly Challenges December 30, 2020
  • Quora: Are Math Courses Useful for Competitive Programming? December 23, 2020
Red-Green-Code
  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter
Copyright © 2021 Duncan Smith