Paying the tab for .NET Native

.NET Native behaves just like that expensive restaurant you love to got to: you have to wait until you finish the meal to see how much it will cost you - and it will definitely cost you!

Last weekend I was confronted with a bug in Cimbalino Toolkit MultiBindingBehavior, which caused apps using it to crash when they were built in Release mode!

I built a small test app and after a couple of minutes debugging it I noticed a MissingMetadataException getting raised; the culprit was found: .NET Native!

If you’re working with Universal Windows Apps (UWP) and don’t know what .NET Native is, I strongly advise you to start by reading the following excellent articles written by Morgan Brown, “a Software Development Engineer on the .NET Native team”:

Here’s the situation right now: when you build a UWP app, the compiler will do some “smart stuff” with your code (let’s skip the technicals here!), squeezing every little bit it can to make sure the compiled result will perform better and faster!

But there is a catch: if your code uses any type of dynamic coding features such as reflection or serialization, you might need to instruct the compiler that certain types in your application will be used as such, in order to avoid the exceptions like the MissingMetadataException you see above.

To avoid such problems, you can add specially built rd.xml files to your project - once again, check the articles above for more information on this subject!

The MultiBindingBehavior works by using the AssociateObject property value to reflect and dynamically create a binding expression, so what I needed was to ensure that it would be able to reflect any object passed to this property.

With this requirement in mind, I created a new Cimbalino.Toolkit.rd.xml file, set its Build Action to Embedded Resource, and set the content to the following:

<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Library Name="Cimbalino.Toolkit">
    <Type Name="Cimbalino.Toolkit.Behaviors.MultiBindingBehavior">
      <Property Name="AssociatedObject" Serialize="Included" />
    </Type>
  </Library>
</Directives>

Aaand… this didn’t work! I started getting a build error message stating that it couldn’t find any AssociatedObject property in the Cimbalino.Toolkit.Behaviors.MultiBindingBehavior.

Granted, the property does not exist directly in this class, but rather in the Behavior<T> base class, so I guess one say that .NET Native compilation completely forgot a completely basic feature of .NET and most object oriented languages: Class Inheritance!

Taking this into account, I made a couple of changes in the file and here’s what in the end made it work:

<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Library Name="Cimbalino.Toolkit" />
  <Library Name="Microsoft.Xaml.Interactions">
    <Type Name="Microsoft.Xaml.Interactivity.Behavior{T}">
      <Property Name="AssociatedObject" Serialize="Included" />
    </Type>
  </Library>
</Directives>

So here’s what I learned in the past weekend:

  • When working with Universal Windows Apps, make sure to build the app in Release mode and test it thoroughly!
  • Keep an eye out on the build warnings for any problems with your rd.xml files.
  • If you’re working with MVVM or have Model representation classes, it might make sense to put these in a separate assembly, or at least in a separate namespace from the rest of the code - this will allow you to easily target these files in a rd.xml for .NET Native optimization exclusion.

XAML Behaviors now open source and on UWP

In case you missed the big news, the XAML Behaviors are now open source in GitHub and available to use in UWP, both in managed and native apps, mostly due to the work of some awesome MVPs!

They were kind enough to keep me in the loop and that allowed me to prepare for the incoming changes! ;)

Cimbalino Toolkit 2.1.0

Version 2.1.0 of the Cimbalino Toolkit is a basic update of the toolkit with a few improvements and bug fixes, but takes into account the new XAML Behaviors:

  • UWP apps it now will pull the XAML Behaviors Managed NuGet package to the projects
  • non-UWP apps will still use the NuGet PowerShell scripts to add the Behaviors SDK

A few weeks ago I introduced the MonitoredInteraction class from Cimbalino Toolkit 2.0.0 to “prevent memory leaks in behaviors”, and I’m happy to say that those changes made it’s way to the XAML Behaviors code! :)

Do notice that while the Interaction class in the XAML Behaviors now performs the proper attach/detach pattern, the same can’t be said for the Behaviors SDK Extension for non-UWP apps, so I strongly advise you to keep using the MonitoredInteraction class for those projects!

One final note: if you actually want to use the XAML Behaviours, you will have to actually manually add the NuGet package to your project… this is due to the new Transitive Dependencies feature of NuGet 3.x, and as far as I know, there is no way of going around this extra step!

CultureInfo changes in UWP

Update: There’s now a part 2 for this article!

Since the very first versions of the .NET Framework, developers had the System.Globalization namespace “containing classes that define culture-related information, including language, country/region, calendars in use, format patterns for dates, currency, and numbers, and sort order for strings.”

One of the most useful classes in this namespace is the CultureInfo class!

To demonstrate the usage of this class, take a look at this really simple console app code:

using System;
using System.Globalization;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("CurrentCulture: {0}", CultureInfo.CurrentCulture);
        Console.WriteLine("CurrentUICulture: {0}", CultureInfo.CurrentUICulture);
    }
}

If you run the above code with different system configurations, this is what it would output:

// Display Language = "English (US)", Location = "United States", Regional Settings = "English (US)"
CurrentCulture: en-US
CurrentUICulture: en-US

// Display Language = "English (US)", Location = "United States", Regional Settings = "Portuguese (Portugal)"
CurrentCulture: pt-PT
CurrentUICulture: en-US

// Display Language = "English (United Kingdom)", Location = "Spain", Regional Settings = "Portuguese (Angola)"
CurrentCulture: pt-AO
CurrentUICulture: en-GB

As you can see from the above results, the CurrentCulture and CurrentUICulture property values are inferred respectively from Regional Settings and Display Language; the Location however, doesn’t seem to have any effect over these two properties.

This feature allowed any app to show data using the proper currency, date, and number formats, even if the app itself wasn’t localized for those cultures!

But then came WinRT with the Windows.Globalization namespace as a replacement, and that apparently affected the way the CultureInfo class behaved…

To show the differences, I’ve created a blank Windows 8 app, and set the following code in the MainView.xaml.cs file:

using System;
using System.Globalization;
using Windows.UI.Popups;
using Windows.UI.Xaml.Controls;

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        this.Loaded += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
    {
        var messageDialog = new MessageDialog(string.Format("CurrentCulture: {0}" + Environment.NewLine + "CurrentUICulture: {1}",
            CultureInfo.CurrentUICulture,
            CultureInfo.CurrentCulture));

        messageDialog.ShowAsync();
    }
}

These are the results of running the above code:

// Display Language = "English (US)", Location = "United States", Regional Settings = "English (US)"
CurrentCulture: en-US
CurrentUICulture: en-US

// Display Language = "English (US)", Location = "United States", Regional Settings = "Portuguese (Portugal)"
CurrentCulture: en-US
CurrentUICulture: en-US

// Display Language = "English (United Kingdom)", Location = "Spain", Regional Settings = "Portuguese (Angola)"
CurrentCulture: en-GB
CurrentUICulture: en-GB

As you can see here, both the CurrentCulture and CurrentUICulture property values are now based on the selected Display Language!

In my personal opinion, this change of behavior is wrong for various reasons, but mostly because it breaks the expected known behavior of the CultureInfo class properties.

Right now you might be thinking that the impact of this change is really small, but it might actually be bigger than expect due to a specific feature: Cortana!

As of today, Cortana is still only available in a few locations, and as such, most users have “faked” their location in order to get Cortana active on their devices, but maintained the Regional Settings matching their real location!

Retrieving the “proper” CurrentCulture

One could use the Windows API GetUserDefaultLocaleName to retrieve the Regional Settings, but this only works on full Windows 10, so it’s not a “universal” way of doing it!

However, I’ve found that if you create a DateTimeFormatter instance with “US” as language, you can retrieve the culture name from the DateTimeFormatter.ResolvedLanguage property!

And here is a simple code example demonstrating how to do it:

using Windows.Globalization.DateTimeFormatting;

public class CultureInfoHelper
{
    public static CultureInfo GetCurrentCulture()
    {
        var cultureName = new DateTimeFormatter("longdate", new[] { "US" }).ResolvedLanguage;

        return new CultureInfo(cultureName);
    }
}

I honestly still don’t know how or why does this work with that Magic String™ (others might also do the trick though), but it does, and at this stage all I care are positive results!

So there you go, this is a nice hack to retrieve a CultureInfo instance for the Regional Settings, which you can then use to parse and format values in your UWP (and WinRT) app! :)

How to prevent memory leaks in Behaviors

Attached Behaviors have been around for quite a while, and though I personally always liked them, they have a fundamental flaw: they can lead to huge memory leaks!

I’ve seen quite a few fixes for them (like this one from MVP Joost Van Schaik), though none proved to be truly “universal” and final!

To demonstrate the problem, let’s take a practical example:

  • create an app with two pages
  • page 1 will have a button to navigate to page 2
  • page 2 will have a button that when clicked, will navigate back to page 1 after a pause of 2 seconds

Here’s the view model for page 2, Page2ViewModel:

public class Page2ViewModel
{
    public event EventHandler GoBack;

    public ICommand DelayedGoBackCommand { get; private set; }

    public MainViewModel()
    {
        DelayedGoBackCommand = new CustomCommand(OnDelayedGoBackCommand);
    }

    private async void OnDelayedGoBackCommand()
    {
        await Task.Delay(2000);

        GoBack?.Invoke(this, EventArgs.Empty);
    }
}

The code is really simple: when the DelayedGoBackCommand gets invoked, we will make a 2 seconds pause, and then raise the GoBack event.

Now lets say that all view models have been registered as singletons in the App class, something like this:

sealed partial class App : Application
{
    public static Page2ViewModel Page2ViewModel { get; } = new Page2ViewModel();

    // remaining code
}

This is the code behind for page 2, where we will set the page view model:

public class Page2
{
    public Page2()
    {
        InitializeComponent();

        DataContext = App.Page2ViewModel;
    }
}

And this is the view we will be using for page 2:

<Page x:Class="MyApp.Page2"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:core="using:Microsoft.Xaml.Interactions.Core"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:i="using:Microsoft.Xaml.Interactivity"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      x:Name="PageRoot"
      mc:Ignorable="d">

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <i:Interaction.Behaviors>
            <core:EventTriggerBehavior EventName="GoBack"
                                       SourceObject="{Binding}">
                <core:CallMethodAction MethodName="GoBack"
                                       TargetObject="{Binding Frame,
                                                              ElementName=PageRoot}" />
            </core:EventTriggerBehavior>
        </i:Interaction.Behaviors>

        <Button Command="{Binding DelayedGoBackCommand,
                                  Mode=OneTime}"
                Content="Go Back" />
    </StackPanel>
</Page>

As you can see above, the button is binded to the Page2ViewModel.DelayedGoBackCommand. Also, we will be using an EventTriggerBehavior to monitor the Page2ViewModel.GoBack event, and when it gets raised, we will use the CallMethodAction to invoke the Page2.Frame.GoBack method.

Now here’s the catch: while behaviors have a way of being notified when they are to be detached, that never happens!! Not when you leave the page, not when the page gets unloaded, and not even when garbage collection runs.

As such, when we navigate back from page 2, Page2ViewModel.GoBack event will still hold a reference to the EventTriggerBehavior, leading to a memory leak!

But things get even worse in this example: everytime we navigate to page 2, we will subscribe over and over again the GoBack event, so multiple invocations will eventually occur - definitely not what we wanted!

Introducing the MonitoredInteraction class

The Cimbalino Toolkit now has the MonitoredInteraction class to solve this issue!

The MonitoredInteraction was built as a direct replacement of the Microsoft.Xaml.Interactivity.Interaction, and will monitor the attached object Loaded and Unloaded events and call for the attachment and detachment of all behaviors it contains!

Here’s how page 2 view would look if put it to use:

<Page x:Class="MyApp.Page2"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:core="using:Microsoft.Xaml.Interactions.Core"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:behaviors="using:Cimbalino.Toolkit.Behaviors"
      x:Name="PageRoot"
      mc:Ignorable="d">

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <behaviors:MonitoredInteraction.Behaviors>
            <core:EventTriggerBehavior EventName="GoBack"
                                       SourceObject="{Binding}">
                <core:CallMethodAction MethodName="GoBack"
                                       TargetObject="{Binding Frame,
                                                              ElementName=PageRoot}" />
            </core:EventTriggerBehavior>
        </behaviors:MonitoredInteraction.Behaviors>

        <Button Command="{Binding DelayedGoBackCommand,
                                  Mode=OneTime}"
                Content="Go Back" />
    </StackPanel>
</Page>

Really, really simple, yet it will finally ensure that behaviors do get detached when one navigates away of a page, and re-attached when navigating in!

Hopefully someone from the Behaviors SDK team will read this, and take some of the suggestions here to fix this well known issue that’s been around for quite a while! ;)

Compiled Bindings considerations

As you’re probably aware, Windows 10 introduced a new type of Bindings called Compiled Bindings.

And as the name might suggest, compiled bindings are a way the compiler uses to generate static code for a binding instead of using a reflection based solution, as regular bindings do.

The main advantage is quite obvious: there will be a performance gain for using static compiled code instead of using reflection!

Let’s take a look at a simple regular binding example:

<TextBlock Text="{Binding Name}" />

This binding will set the TextBlock.Text property to the value of the Name and will update it every time the Name property changes (assuming that the data context implements and raises the necessary INotifyPropertyChanged.PropertyChanged event)

To take advantage of the compiled bindings, one would rewrite it like this:

<TextBlock Text="{x:Bind Name, Mode=OneWay}" />

Notice that I added the Mode=OneWay on the expression above?

Well, that is actually required due to a fundamental difference between regular bindings and compiled bindings: while the regular bindings default mode is OneWay, compiled bindings default mode is OneTime!

This is a really important piece of information that I’ve seen a lot of developers not taking notice, so make sure to fix those binding expressions correctly when you migrate to compiled bindings!

Cimbalino Toolkit 2.0.0 (final)

Bring out the champagne, because Cimbalino Toolkit version 2.0.0 has gone “gold” and is now production ready! :)

As previously stated, the focus for this new version was to add support for UWP (Universal Windows Platform), thus making the toolkit support a total of 4 platforms:

  • Windows Phone Silverlight 8.0 and 8.1 apps (WP8)
  • Windows Phone 8.1 apps (WPA81)
  • Windows Store 8.1 apps (Win81)
  • Windows 10 UWP apps (Universal Windows Platform)

Please remember to manually add the Behaviors SDK to your UWP apps if you use Cimbalino! The other platforms will have it added automatically, but due to changes in the way NuGet works this is not possible for UWP.

Cimbalino Toolkit 2.0.0-beta1

Assuming you don’t live in a planet where you don’t get internet (and I know that’s not the case as you’re reading this!), by now you know that Windows 10 has officially launched!

So did Visual Studio 2015 and NuGet 3.x, so pretty much everything you need to develop new Windows 10 universal apps, right? Not quite! ;)

Presenting the new and improved version 2.0.0-beta1 of the Cimbalino Toolkit, and as you already suspect, it is fully compatible with UWP (Universal Windows Platform)!

Proper kudos is owed to MVP Scott Lovegrove as he has done pretty good job for the last couple of weeks to get the toolkit up and running in Windows 10! :)

There is a breaking change on using the toolkit from previous versions: NuGet has removed the functionality of running Powershell scripts when you install a package, and Cimbalino Toolkit required that to add the Behaviors SDK to your projects… that said, please make sure that you manually add the Behaviors SDK to any project using the Cimbalino.Toolkit NuGet package!

On a final now, remember that this new version is still a beta as the code and documentation will be reviewed and tested during the next weeks, so do expect to find some issues and bugs! If you find any, please do report them directly on GitHub!

There’s never been a better time to be a Microsoft developer!

Full disclosure: though I’ve been a Microsoft employee for a short while, I currently have no professional (or other type of) connection with the company.

Now that we have got that out of the way, I do believe that there has never been a better time to be a Microsoft developer than today! :)

Ok, I’ll bite… why do you think that?

Microsoft Build Developers Conference was held last week in San Francisco. On it, Microsoft showed it’s vision for the future, and it is a bright one!

Though this article only scratches the surface on all that was shown, these were my personal highlights of the event!

Windows 10 everywhere!

Yes, Windows 10 will be everywhere, from PC’s, Laptops and Tablets, the Xbox One and Hololens, and also powering IoT devices like the Raspberry Pi 2.

For developers this translates in the fact that apps you develop for Windows 10, will also run in any other device! Functionality may obviously differ from device to device given their capabilities (touch screen on a tablet, augmented reality in Hololens, sensors on IoT devices, etc.), but in the end it will be the same Windows 10 app running on all of them!

Open-source initiative

The amount of code made available over the last couple of weeks in Microsoft’s GitHub page is truly astonishing!

Microsoft went from a closed-source software company to open-source a big chunk of their code in order to get contributions from the community (comments, reviews, code contributions, etc.), just like in any other GitHub repository!

Going cross-platform

Say goodbye to the Microsoft you’ve know for years as a Windows and Office only company; “Mobile first, cloud first” is the new motto, and there was enough proof of that in Build conference.

If you’re a web developer, you should definitely give Visual Studio Code a spin - and here’s the twist: it runs not only in Windows, but also in Mac and Linux, as Visual Studio Code is itself built on top of open-source technologies!

The whole CoreCLR (.NET Core Runtime) was built for Windows but now runs in Mac and Linux machines, meaning you can run the same .NET based code in all these platforms!

iOS and Android apps are welcome!

Develop apps for iOS or Android? Well, there’s some good news for you too: with Project Islandwood and Project Astoria, you’ll be able to make those apps run in Windows 10 with just a few modifications, and even sell them through the Windows Store and make some money out of it!

Targeting the Windows platform is definitely a smart move, as it will enable you to reach more users and increase potential revenue from your apps.

All apps are now Windows Apps

The “older” .NET and Win32 desktop apps we use all day long will now have a place in the Windows Store, making life easier for users to find, download and use them!

Just package those apps as a Windows 10 app, ship it to the store, and you’re done!

One more thing

Hololens! If you don’t know what it is by now, then you definitely should!!

While other companies are investing Virtual Reality, Microsoft took a different approach with Hololens and went with Augmented Reality.

As the name might suggest, “Augmented Reality” adds information to your real environment, and it’s usages are quite diverse. Microsoft showed a couple of demos of usage for construction and health that I believe made some jaw’s drop!

“DEVELOPERS, DEVELOPERS, DEVELOPERS!!”

No one said it, but I’m sure a lot of people remembered this while watching Build 2015:

https://www.youtube.com/watch?v=Vhh_GeBPOhs