Implementing Toggle Buttons in Xamarin Forms

Introduction

One control that Xamarin has seemingly left out of its library of controls is a toggle button, sometimes known as a radio button. I recently ran into a use case for one so I worked out an implementation that I think is both clean and reusable. I’m going to demonstrate it here and show you how you too can implement this really useful control.

Design Requirements

First lets talk about my needs for this particular implementation as it may help you to understand some of the decisions that were made in coming up with this design. In my particular application, I have a main view that has two available views (grid and list) and I wanted to toggle between those views. Because each view mode corresponded to a different layout object type, it made sense to do this via enum.

If you are interested in the list control being used, check out Syncfusion’s awesome control library for Xamarin forms. It provides may of the features that Telerik provides but also has a free option for independent developers and > small businesses.

public enum ViewType
{
    Grid,
    List
}

Implementation

Toggle Button

Because this toggle button set was going to appear in something akin to a toolbar, I chose to implement this as an image only button. Further, I wanted fine tune control of margins around my images and toggle a background when the button was selected. To facilitate this, I created a custom ToggleButton control.

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Core.Controls.ToggleButton">
    <ContentView.GestureRecognizers>
        <TapGestureRecognizer x:Name="TapGesture" />
    </ContentView.GestureRecognizers>

    <Grid>
        <Image Margin="2,2,2,2" x:Name="ImageView" />
    </Grid>
</ContentView>

The interface for this is very simple. Note the tap gesture recognizer used to capture “clicks”. Most of the implementation is contained in code-behind.

public partial class ToggleButton
{
    public static readonly BindableProperty ImageProperty = BindableProperty.Create(
        nameof(Image), typeof(ImageSource), typeof(ToggleButton), propertyChanged: OnImageChanged);

    public static readonly BindableProperty CommandProperty = BindableProperty.Create(
        nameof(Command), typeof(ICommand), typeof(ToggleButton), propertyChanged: OnImageChanged);

    public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(
        nameof(CommandParameter), typeof(object), typeof(ToggleButton), propertyChanged: OnImageChanged);

    private static void OnImageChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (!(bindable is ToggleButton control))
            return;

        control.ImageView.Source = control.Image;
    }

    public ToggleButton ()
    {
        InitializeComponent ();
        TapGesture.Command = TapCommand;
    }

    public event EventHandler<object> Clicked;

    public ImageSource Image
    {
        get => (ImageSource) GetValue(ImageProperty);
        set => SetValue(ImageProperty, value);
    }

    public ICommand Command
    {
        get => (ICommand )GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    public object CommandParameter
    {
        get => GetValue(CommandParameterProperty);
        set => SetValue(CommandParameterProperty, value);
    }

    private ICommand TapCommand => new Command(() =>
    {
        Clicked?.Invoke(this, CommandParameter);
        Command?.Execute(CommandParameter);
    });
}

Here, I have implemented 4 very familiar properties. Note the private command TapCommand. This is assigned to the tap gesture recognizer in code-behind so that we can both fire the Clicked event and call the bound command. This will come in handy later. Further, we have bindable properties for the image to display and the parameter to pass to the command. When the user taps the button, it both fires the event and executes the command, passing CommandParameter to both.

In hindsight, after a few revisions, this control is less of a toggle button and more of just a regular button that exposes propeties that are useful for this case. You could easily use a similar approach with some other control being toggled.

Toolbar Implementation

This is where it starts to get a little interesting. The tool bar is the control which contains the set of ToggleButton. The XAML code starts off in a very uninteresting fashion. Notice we have bound shared commands to each of the buttons and instead opted to pass our enum type as a parameter. Each button also gets its own image set.

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:Core.Controls"
             xmlns:pageModels="clr-namespace:Core.PageModels"
             x:Class="Core.Controls.ToolbarControl">
    <StackLayout Orientation="Horizontal">
        ...
        <controls:ToggleButton x:Name="ListButton" Image="ListView"
                               Command="{Binding ChangeViewCommand}"
                               CommandParameter="{x:Static pageModels:ViewType.List}" />
        <controls:ToggleButton x:Name="GridButton" Image="GridView"
                            Command="{Binding ChangeViewCommand}"
                            CommandParameter="{x:Static pageModels:ViewType.Grid}" />
        ...
    </StackLayout>
</ContentView>

As an aside, note the syntax used to reference the enum value. We are able to treat it as if it were another static reference and easily pass it as the parameter. This is a little XAML nugget that I think some people miss.

The code-behind looks like this. Because this control is split off from its container page, we expose a few bindable properties. First, we define the current view type using our enum. Note that the binding on this is two way. This is critical as this needs to be changeable in both our consuming view model and within the control itself. We also provide a command to change the view (which is passed on to the buttons themselves) and our implementation exposes a property to set the selected background color.

Aside #2. Please note the OnParentSet override. I see people forget this all the time and it can be very important. Note that when the parent is not null we know the control has just been attached. This is when we take the time to subscribe to necessary events. However, many developers overlook unsubscribing from those events as well. Failure to do so will leave dangling references and cause the object to not be garbage collected, thus leaking memory. In a Page you can do something similar with the OnAppearing and OnDisappearing overrides. Always ensure you have a matching unsubscribe for each event subscription. This has been a public service announcement from your friendly neighborhood unmanaged developer.

public partial class ToolbarControl
{
    public static BindableProperty CurrentViewTypeProperty = BindableProperty.Create(
        nameof(CurrentViewType), typeof(ViewType), typeof(ToolbarControl), ViewType.List, BindingMode.TwoWay, propertyChanged: OnUpdateNeeded);

    public static BindableProperty SelectedColorProperty = BindableProperty.Create(
        nameof(SelectedColor), typeof(Color), typeof(ToolbarControl), Color.White, propertyChanged: OnUpdateNeeded);

    private static void OnUpdateNeeded(BindableObject bindable, object oldValue, object newValue)
    {
        if (!(bindable is ToolbarControl control))
            return;

        if (control.CurrentViewType == ViewType.Grid)
        {
            control.GridButton.BackgroundColor = control.SelectedColor;
            control.ListButton.BackgroundColor = Color.Transparent;
        }
        else
        {
            control.ListButton.BackgroundColor = control.SelectedColor;
            control.GridButton.BackgroundColor = Color.Transparent;
        }
    }

    public ToolbarControl ()
    {
        InitializeComponent();
    }

    protected override void OnParentSet()
    {
        base.OnParentSet();
        if (null == Parent)
        {
            GridButton.Clicked -= OnClicked;
            ListButton.Clicked -= OnClicked;
        }
        else
        {
            GridButton.Clicked += OnClicked;
            ListButton.Clicked += OnClicked;
        }
    }

    public ViewType CurrentViewType
    {
        get => (ViewType) GetValue(CurrentViewTypeProperty);
        set => SetValue(CurrentViewTypeProperty, value);
    }

    public Color SelectedColor
    {
        get => (Color)GetValue(SelectedColorProperty);
        set => SetValue(SelectedColorProperty, value);
    }

    private void OnClicked(object sender, object args)
    {
        CurrentViewType = args is ViewType viewType ? viewType : ViewType.Grid;
    }
}

Other features of note here is the click handler itself which merely sets the current view type. Because this is a bindable property, the property changed handler is also called. We see that that simply checks the CurrentViewType property and sets the control backgrounds accordingly.

Scalability

Granted, this is a very simple implementation. I originally wrote the more complex version but scaled it back when I realized it was overkill for me. In that case, the ToggleButton control had a static field of type IDictionary<string, IDictionary<string, ToggleButton>> which contained state data. It also had a string property for the toggle set name and a control identifier. This allowed for multiple toggle sets with varying numbers of controls. As the buttons were initialized, they populated the state dictionary (and cleaned up afterwards). When a button was hit, it was able to look up all other buttons in its set and modify their properties appropriately.

If there is interest in this implementation, I will gladly write about it in the future.

Putting It All Together

Now all that remains is using it. The XAML is trivial.

<controls:ToolbarControl SelectedColor="{StaticResource LightGreyColor}"
                         CurrentViewType="{Binding CurrentViewType}"/>

Furthermore, the code-behind is fairly common, and would likely be considered implementation specific.

public abstract class ExplorerPageModel : PageModelBase
{
    private ViewType _currentViewType;
    private LayoutBase _currentLayout;
    ...
    public ViewType CurrentViewType
    {
        get => _currentViewType;
        set
        {
            SetProperty(ref _currentViewType, value);
            SetLayoutForView(value);
        }
    }

    public LayoutBase CurrentLayout
    {
        get => _currentLayout;
        private set => SetProperty(ref _currentLayout, value);
    }

    private void SetLayoutForView(ViewType viewType)
    {
        CurrentLayout = new ExplorerLayoutConverter()
            .Convert(viewType, typeof(object), null, CultureInfo.InvariantCulture) as LayoutBase;
    }
    ...
}

As you can see, this is fairly implementation specific. We handle the view type changing in its setter, updating the LayoutBase instance that is bound to our list view. In theory, many things could be done here. All that is needed is to react to the toggle value changing. All visual changes are handled at the control level here. Finally, for completeness, I include the converter used here. This should not be that surprising to anyone.

public class ExplorerLayoutConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is ViewType type))
            throw new ArgumentOutOfRangeException();

        switch (type)
        {
            case ViewType.Grid:
                return new GridLayout { SpanCount = 3 };
            case ViewType.List:
                return new LinearLayout();
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Bonus 1: Checkbox Implementation

I mentioned that many of the choices here were made based on my actual design specs. As a small bonus, let’s talk about how you could use this to implement a check box. At it’s core, a checkbox is simple a radio button with a single option that can be turned on or off. So, rather than a ViewType you would only track a single bool. Also, on click, rather than changing a background you would simply change the image displayed on the button itself. Your resources could contain a checked and unchecked state.

This might not be the best implementation, but it might be useful in the case you are already implementing a toggle button set as well.

Bonus 2: Push Button Animation

As a final bonus, I mentioned that I wanted to simulate the push of a tool bar button. I have implemented this using Behaviors and Xamarin Forms’ built in animation methods.

Behaviors are a newer feature, and as a former C++ developer who still misses multiple inheritance sometimes, behaviors are awesome because they allow you to implement “composition” of features in your controls without going to the trouble of a renderer. Take push button animation as an example.

public class AnimatedButtonBehavior : BindableBehavior<ToggleButton>
{
    protected override void OnAttachedTo(ToggleButton bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.Clicked += OnClicked;
    }

    protected override void OnDetachingFrom(ToggleButton bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.Clicked -= OnClicked;
    }

    private async void OnClicked(object sender, object eventArgs)
    {
        if (AssociatedObject == null)
            return;

        AssociatedObject.AnchorX = 0.48;
        AssociatedObject.AnchorY = 0.48;
        await AssociatedObject.ScaleTo(0.8, 50, Easing.Linear);
        await Task.Delay(100);
        await AssociatedObject.ScaleTo(1, 50, Easing.Linear);
    }
}

This makes use of a class that, for me, is pretty much an auto-include in any Xamarin Forms project, the BindableBehavior. I don’t remember where I got my implementation from, so for academic reasons I will point you to the version here. This class is like any MVVM class implementation. There are many out there and they all do more or less the same thing.

public class BindableBehavior<T> : Behavior<T> where T : BindableObject
{
    public T AssociatedObject { get; private set; }

    protected override void OnAttachedTo(T visualElement)
    {
        base.OnAttachedTo(visualElement);

        AssociatedObject = visualElement;

        if (visualElement.BindingContext != null)
            BindingContext = visualElement.BindingContext;

        visualElement.BindingContextChanged += OnBindingContextChanged;
    }

    private void OnBindingContextChanged(object sender, EventArgs e)
    {
        OnBindingContextChanged();
    }

    protected override void OnDetachingFrom(T view)
    {
        view.BindingContextChanged -= OnBindingContextChanged;
    }

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        BindingContext = AssociatedObject.BindingContext;
    }
}

The idea here is to track changes in binding context and set it appropriately within the behavior. For convenience, we also track the attached object in the AssociatedObject property. In our behavior, we simply hook into the Clicked event of the button (which is why we added both events and commands to the ToggleButton to begin with) and fire an animation asynchronously when it fires. This allows us to separate the animation behavior from the business logic in our view models. Implementing this changes our ToolbarControl so that we set the Behaviors collection on our ToggleButton.

 <controls:ToggleButton x:Name="ListButton" Image="ListView"
                               Command="{Binding ChangeViewCommand}"
                               CommandParameter="{x:Static pageModels:ViewType.List}">
    <controls:ToggleButton.Behaviors>
        <behaviors:AnimatedButtonBehavior>
    </controls:ToggleButton.Behaviors>
</controls:ToggleButton>

Becuase the Behaviors property is a collection, you could list multiple behaviors in a list and achieve the “composition” of various features while still separating them in a logical fashion. This is classic “favor composition over inheritance” mindset I was referring to.

Wrap Up

That’s all for now, folks. Hopefully you found this implementation useful and maybe even picked up a trick or two. Feel free to hit up the comment section below with questions.

Handling Configuration in Xamarin

One of the great things about .NET Core is it’s high level of customization. You can opt-in to and configure almost anything an app would need without inheriting any of the cruft you don’t. To achieve this, the team implemented a very high level of modularity. Things that would have shipped with the framework before were broken out into separate NuGet packages. One of my favorites is the Microsoft.Extensions.Configuration package. Consumers can leverage this into a highly customized configuration for their application which can draw on multiple sources in such a way that makes app.config files and transformations weak in the knees. In this article, I’m going to show you how to leverage this in your Xamarin mobile apps to create application configs that can meet any need.

The New Standard

The first thing you need to do is get rid of those PCLs. This has been covered in many other places and is beyond the scope of this article, but I will include a sample project here for readers to extrapolate from. There are a few important parts to point out. First, we target .NET Standard 2.0 here. This is supported as of Xamarin Forms 2.4 which was recently released. In this scenario, we also want to define the AssetTargetFallback. In previous versions of the standard, this was called the TargetPlatformFallback but the purpose is more or less the same. By setting this, we are saying that we accept PCL packages which support the defined platforms as dependencies when pulling from NuGet. Not all packages have migrated but most are still compatible with the standard.

The next thing you will notice is are NuGet references defined inline. We no longer need a packages.config file to list out our dependent packages. Sometimes you will see NoWarn="NU1701" to suppress a NuGet error warning when a package is pulled due to the AssetTargetFallback setting above.

The final part of this project extends the default MSBuild rules for XAML files. We update the rules for .xaml.cs files to add the DependentUpon attribute that you would see in old PCL project files. This creates the hierarchy you are used to seeing in the IDE for code-behind files. Second, we add a rule that globs all XAML files and defines them as EmbeddedResources. This isn’t really different in practice than old style .csproj files, however it is much more succinct and easy to maintain. It also allows us to leverage the configuration packages you see references to.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81</AssetTargetFallback>
    <RootNamespace>ConfigurationSample.Core</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Xamarin.Forms" Version="2.4.0.283" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
    ...
  </ItemGroup>

  <ItemGroup>
    <Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
    <EmbeddedResource Include="**\*.xaml" SubType="Designer" Generator="MSBuild:UpdateDesignTimeXaml" />
  </ItemGroup>
</Project>

What’s the Configuration, Kenneth

So, now that we are using .NET Standard, how do we implement configuration in our Xamarin app? First, let’s look and see what happens in a typical .NET Core web application. From Microsoft’s own documentation, we see an app who loads appsettings.json from the root directory of the app and builds a configuration out of it. This Configuration object could then be saved in your IoC container, set as a static property on some root object, or thrown away after using it. Further, this example shows how you can leverage nesting in your JSON file.

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

public class Program
{
    public static IConfigurationRoot Configuration { get; set; }

    public static void Main(string[] args = null)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");

        Configuration = builder.Build();

        Console.WriteLine($"option1 = {Configuration["option1"]}");
        Console.WriteLine($"option2 = {Configuration["option2"]}");
        Console.WriteLine(
            $"suboption1 = {Configuration["subsection:suboption1"]}");
        Console.WriteLine();

        Console.WriteLine("Wizards:");
        Console.Write($"{Configuration["wizards:0:Name"]}, ");
        Console.WriteLine($"age {Configuration["wizards:0:Age"]}");
        Console.Write($"{Configuration["wizards:1:Name"]}, ");
        Console.WriteLine($"age {Configuration["wizards:1:Age"]}");
        Console.WriteLine();

        Console.WriteLine("Press a key...");
        Console.ReadKey();
    }
}
{
  "option1": "value1_from_json",
  "option2": 2,

  "subsection": {
    "suboption1": "subvalue1_from_json"
  },
  "wizards": [
    {
      "Name": "Gandalf",
      "Age": "1000"
    },
    {
      "Name": "Harry",
      "Age": "17"
    }
  ]
}

While simple, this example exposes a major problem when porting to Xamarin. We don’t have a root directory from which to load a JSON file. If we assume this is the easiest way to store the information we need (and it probably is), we need to be able to load files from somewhere else. If we explore the API, we find that there is an override AddJsonFile(IFileProvider, string, bool, bool). The key here is the IFileProvider interface. For reference, the interface is included here. This interface gets implemented by any system that can provide configuration information. For JSON files coming from disks, this interface will read the file system and return data appropriately.

/// <summary>A read-only file provider abstraction.</summary>
public interface IFileProvider
{
    /// <summary>Locate a file at the given path.</summary>
    /// <param name="subpath">Relative path that identifies the file.</param>
    /// <returns>The file information. Caller must check Exists property.</returns>
    IFileInfo GetFileInfo(string subpath);

    /// <summary>Enumerate a directory at the given path, if any.</summary>
    /// <param name="subpath">Relative path that identifies the directory.</param>
    /// <returns>Returns the contents of the directory.</returns>
    IDirectoryContents GetDirectoryContents(string subpath);

    /// <summary>
    /// Creates a <see cref="T:Microsoft.Extensions.Primitives.IChangeToken" /> for the specified <paramref name="filter" />.
    /// </summary>
    /// <param name="filter">Filter string used to determine what files or folders to monitor. Example: **/*.cs, *.*, subFolder/**/*.cshtml.</param>
    /// <returns>An <see cref="T:Microsoft.Extensions.Primitives.IChangeToken" /> that is notified when a file matching <paramref name="filter" /> is added, modified or deleted.</returns>
    IChangeToken Watch(string filter);
}

The trick getting configuration on Xamarin is implementing this in such a way that mobile apps can access configuration files. The first thing that comes to mind is bundling config files with the embedded resources (just like compiled XAML files are) and reading them from there using reflection at runtime. The implmentation will be listed here.

This is the top level interface implmentation. It exists only to create instances of other interfaces which we also define.

public class ResourceFileProvider : IFileProvider
{
    public IFileInfo GetFileInfo(string subpath)
    {
        return new ResourceFileInfo(subpath);
    }

    public IDirectoryContents GetDirectoryContents(string subpath)
    {
        return new ResourceDirectoryContents();
    }

    public IChangeToken Watch(string filter)
    {
        return new ResourceChangeToken();
    }

}

This is our implementation of IDirectoryContents. We don’t implement an enumerator simply because we don’t need one. This is really just a no-op implmentation.

public class ResourceDirectoryContents : IDirectoryContents
{
    public IEnumerator<IFileInfo> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Exists { get; }
}

The crux of the implementation lies here. We make the assumption that configuration files are in the root folder for simplicity. When creating the stream, we use reflection to return the resource stream. All other properties are defined relative to this.

public class ResourceFileInfo : IFileInfo
{
    public ResourceFileInfo(string path)
    {
        PhysicalPath = path;
        Name = Path.GetFileName(path);
    }

    public Stream CreateReadStream()
    {
        var assembly = typeof(ResourceFileInfo).GetTypeInfo().Assembly;
        return assembly.GetManifestResourceStream(PhysicalPath);
    }

    public bool Exists
    {
        get
        {
            var assembly = typeof(ResourceFileInfo).GetTypeInfo().Assembly;
            return assembly.GetManifestResourceNames().Contains(Name);
        }
    }

    public long Length => CreateReadStream().Length;
    public string PhysicalPath { get; }
    public string Name { get; }
    public DateTimeOffset LastModified => DateTimeOffset.Now;
    public bool IsDirectory => false;
}

As these files are resources, changes are impossible so we essentially disable any change tokens.

public class ResourceChangeToken : IChangeToken
{
    public IDisposable RegisterChangeCallback(Action<object> callback, object state) => Disposable.Empty;
    public bool HasChanged => false;
    public bool ActiveChangeCallbacks => false;
}

Using this implmentation, configuring your Configuration system is now easy.

Put It All Together

First, we need to embed the configuration. Go back to your shared project configuration and make the appropriate changes.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81</AssetTargetFallback>
    <RootNamespace>ConfigurationSample.Core</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Xamarin.Forms" Version="2.4.0.283" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
    ...
  </ItemGroup>

  <ItemGroup>
    <Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
    <EmbeddedResource Include="**\*.xaml" SubType="Designer" Generator="MSBuild:UpdateDesignTimeXaml" />
  </ItemGroup>

  <ItemGroup>
    <None Remove="Config\*.json" />
    <EmbeddedResource Include="Config\config.debug.json" Condition="'$(Configuration)'=='Debug'" LogicalName="config.json" />
    <EmbeddedResource Include="Config\config.release.json" Condition="'$(Configuration)'!='Debug'" LogicalName="config.json" />
    <EmbeddedResource Include="Config\platform.android.json" Condition="'$(Platform)'=='Android'" LogicalName="platform.json" />
    <EmbeddedResource Include="Config\platform.ios.json" Condition="'$(Platform)'!='Android'" LogicalName="platform.json" />
  </ItemGroup>
</Project>

Now, what the heck have I done here? For my particular example, I wanted to have separate Debug and Release configuations so that I could define different backends. However, I also have things like HockeyApp IDs that are defined per platform. So, I have devised a system with four separate configuration files. In the project file, I use build variables to map either config.debug.json or config.release.json to a single resource file named config.json. This will be included as an embedded resource file. Similarly, I have platform.android.json and platform.ios.json which get mapped to platform.json in the resource manifest.

Your situation here can always vary. That is really what is great here. We can create a configuration layout that meets our needs exactly. In an upcoming state we will even define the load order so if two files share a setting, the one that is loaded last will take priority.

Speaking of loading these files, remember that .NET Core example I showed earlier where we loaded appsettings.json? Well now we can do something very similar. You can do this in many places, but I do it in my platform dependent startup code. For iOS, I have the following.

[Register("AppDelegate")]
internal class AppDelegate : FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
    {
        var config = new ConfigurationBuilder()
            .AddJsonFile(new ResourceFileProvider(), "config.json", false, false)
            .AddJsonFile(new ResourceFileProvider(), "platform.json", false, false)
            .Build();

        // Register this with your IoC container

        Forms.Init();

        LoadApplication(new App());
        return base.FinishedLaunching(uiApplication, launchOptions);
    }
}

Notice how we call AddJsonFile with our newly created ResourceFileProvider implementation and pass the logical name of the config file as we added it to the project. That’s it! The config object is now a key-value store with all of your parameters loaded. You can query child objects and return other configuration values with their parameters just like you would in your .NET Core app.

Safety First

Let’s go a step further. No one wants to remember key names when querying these values. Let’s add some type safety. We do this by creating a POCO (plain old C object) that describes our configuration model and adding ONE line to the startup configuration. Let’s do it. First, the model object.

public class Configuration
{
    public string HockeyAppKey { get; set; }
    public ApiConfiguration Api { get; set; }
}

public class ApiConfiguration
{
    public string Root { get; set; }
    public string Client { get; set; }
    public string Secret { get; set; }
    public string GrantType { get; set; }
}

config.debug.json

{
    "Api": {
        "Root": "https://yourapiroot.com",
        "Client": "*******",
        "Secret": "******",
        "GrantType": "password"
    }
}

platform.ios.json

{
    "HockeyAppKey": "*******"
}

Note that I mirror the structure of the configuration files here as well. For reference, I also listed debug and iOS configuration files. Note how these are melded together to form a single configuration model. Now, we perform the mapping. In the startup (AppDelegate for instance on iOS):

[Register("AppDelegate")]
internal class AppDelegate : FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
    {
        var config = new ConfigurationBuilder()
            .AddJsonFile(new ResourceFileProvider(), "config.json", false, false)
            .AddJsonFile(new ResourceFileProvider(), "platform.json", false, false)
            .Build()
            .Get<Configuration>();

        // Register this with your IoC container

        Forms.Init();

        LoadApplication(new App());
        return base.FinishedLaunching(uiApplication, launchOptions);
    }
}

Note the single addition of the call to Get<TConfigModel>(). Now, rather than a key-value dictionary, we get an instance of the model object we defined.

Wrap Up

Hopefully you see the usefulness of this beyond a simple app.config. This seems (to me at least) much more maintainable when compared to app.config transforms and much easier to use once its setup. I’d love to hear what you think in the comments. Next up, I may wrap this implemenation up into a more usable NuGet package for people to consume if there is enough demand.

The following is cross-posted with permission of my employer and is an example of some of the content we are producing over at Anexinet. Please check it out.

It’s not uncommon in the IT industry to hear people rave about the next big thing and subsequently to sit there wondering, “Just what the heck is it and why do I care?” Node.js certainly seems to be one of those technologies, and frankly, their own answer to this question doesn’t help:

“Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.” - nodejs.org

And we still wonder…. So, let’s break it down. There seems to be 3 main pieces to the above statement.

  1. “… is a JavaScript runtime built on Chrome’s V8 JavaScript engine….”
  2. “… uses an event-driven, non-blocking I/O model….”
  3. “… package ecosystem, npm, is the largest ecosystem of open source libraries in the world.”

JavaScript meets Server

Unlike many computer languages which are compiled, JavaScript is an interpreted language. This means that rather than feeding code through a program that generates a binary, JavaScript code runs through an interpreter which executes the code in real time. Any application which wises to run JavaScript code needs such an interpreter. There are many available, but one of the most popular ones is Chrome’s V8 engine. This engine’s SOLE job is to execute JavaScript code. As such, it is not JavaScript code itself (for the most part) but rather compiled C++ code. This helps to ensure it can run as fast as possible on the hardware it is compiled for.

To implement JavaScript, applications (like web browsers) include an engine as a library. For example, Google’s Chrome browser includes the V8 engine. When the web browser needs to execute JavaScript, they pass it on to the V8 engine to do so.

What does this mean for node.js? Well node.js is simply another program which includes the V8 engine as a library. That gives it the ability to execute JavaScript code. Like V8, node is written in C++ to help with performance.

One of the main benefits of doing this is the ability to modify the JavaScript language. V8 provides extension points allowing implementers to add features to the language as they wish. Node.js takes advantage of this to create its own API that adds many platform-specific functions to a language that normally would not allow this. Node has the ability to access the file system, initiate and receive HTTP requests, and manage OS processes. JavaScript normally does not allow for this, but by extending V8 node is able to allow this.

By including the V8 engine, or rather building on top of it as the website states, node.js becomes a viable method of running JavaScript directly on hardware. This opens up the ability to do so as a server backend, and indeed that is its chief purpose.

But servers need to scale?

JavaScript by itself is a synchronous language. It allows for callbacks to be used easily, but code is still executed synchronously within the interpreter. This is problematic in a server environment where your app needs to handle many requests simultaneously. This is where the second point from above comes into play.

Node.js uses the libuv library to implement an event loop. This loop is constantly monitoring an event queue and processing entries off that queue in a synchronous matter. However, items can be pushed onto that queue in an asynchronous manner from the C++ portions of node and the V8 engine.
So, incoming network requests coming from the operating system can be processed asynchronously, put on to the event queue where node processes them one at a time.

Node.js event queue

A package manager to die for…..

You may think I’m exaggerating but you couldn’t be more wrong. Npm is the package manager developers wish they had on every platform. A single file (package.json) contains everything you need to define a project and developers can easily add and remove dependencies. It even enables simple project scripting to define your build process. Npm is so well designed, in fact, that its not uncommon to see non-node Java-Script projects using it. If you’re doing JavaScript, and you aren’t using npm you are doing it wrong.

Why this blog?

This is the first of what I hope is many posts to this blog. Any competent programmer comes across a myriad of problems on a day to day basis and some of these problems require a bit of creativity and outside of the box thinking to get through them. I hope to document some of the more interesting ones I come across myself during both my work and personal efforts.

Some of the issues I come across may not be totally public information. In those cases, I will sanitize the example such that I can disclose the information without violating any confidentiality.

Topics of discussion

The primary purpose of this site will be to discuss interesting issues in software engineering and architecture. However, I reserve the right to discuss a multitude of topics. These could include gaming, pop culture, politics or finance. As the disclaimer states, all opinions are my own and do not represent my employer.

Consultation

Speaking of employer, I do occasionally take on consulting projects. If you are interested in discussing your needs, feel free to get in touch.