Using MVVM Light in Universal Windows Apps

I though it would be interesting to see how easy it is to define an MVVM Light view model once and then use it in both a Universal Windows Phone and Windows Store project.

So I created a new blank universal apps project and added the “MVVM Light libraries only (PCL) NuGet” package to both the Windows 8.1 project and the Windows Phone 8.1 project.

Next create a new view model class in the shared project:

using System.Linq;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

namespace UniMvvmLight
{
    class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            Words = "Hello";

            Reverse = new RelayCommand(() =>
                                       {
                                           Words = new string(Words.ToCharArray().Reverse().ToArray());
                                       });
        }

        private string _words;
        public RelayCommand Reverse { get; set; }

        public string Words
        {
            get
            {
                return _words;
            }
            set
            {
                Set(() => Words, ref _words, value);                
            }
        }
    }
}

I’m not going to create a view model locator etc, just simply set the datacontext in the code behind of both the phone and store MainWindow:

public MainPage()
{
    this.InitializeComponent();

    this.DataContext = new MainViewModel();
}

Next define the xaml in both the MainWindow.xaml in both phone and store projects:

<Grid>
    <StackPanel>
        <TextBox Text="{Binding Words}"></TextBox>
        <Button Command="{Binding Reverse}">Reverse</Button>
    </StackPanel>
</Grid>

Now running either the phone or store app works as expected, the view model binding works as expected and clicking the button reverses the string as expected. Whilst this is not surprising, the view model in the shared project is just like having a copy of it in both app projects, even so it’s still cool.

Windows phone simulator

If we wanted to we could then leverage C# partial classes and methods to define platform-specific viewmodel code.

SHARE:

Leveraging C# Partial Classes and Methods in Windows Universal Apps

There’s a number of ways we could implement platform specific code in Windows Universal Apps which I’ll cover in future articles.

In this article we’ll look at an often underused feature of C#: partial classes and methods.

Quick Overview

Partial classes allow us to split the definition of a class over multiple .cs files. The files all contain the same namespace and class names, but the class name is preceded by the partial keyword modifier.

Partial methods allow a method to be defined but that doesn’t contain an implementation, the implementation can then be provided in another partial class file.

(Check out my C# Tips eBook for more info on partial types.)

Using Simple Conditional Compilation Directives

If you want to get an overview of Universal Apps, check out this previous article.

For the sake of this demo, say we have a class “Identity” that displays a message box stating whether we’re in a Windows Store or Phone app.

We could do this using conditional directives:

using System;
using System.Threading.Tasks;
using Windows.UI.Popups;

namespace UsingPartials
{
    public class Identity
    {             
        public async Task WhoAmI()
        {
            string message = CalcMessage();

#if WINDOWS_APP

            message = "I'm a Windows Store App!";

#elif WINDOWS_PHONE_APP

            message = "I'm a Windows Phone App!";            

#endif

            var dialog = new MessageDialog(message);
            await dialog.ShowAsync();
        }
        
    }
}

And from a button click event handler in both the apps:

private async void WhoAmI_Click(object sender, RoutedEventArgs e)
{
    var id = new Identity();

    await id.WhoAmI();
}

Clicking the button in the apps results in the following message boxes being displayed:

image

 

image

 

Refactoring to Partial

So this is a simple example, but if there were lots of these conditional directives, we can tidy things up a little.

The idea is that the shared class “Identity” is made partial:

public partial class Identity

This class still contains the method that’s called from each of the apps, but this time the creation of the content of the message is delegated to a method called “CalcMessage”. This method sets the private field to be used in the dialog.

In the “Identity” class, the “CalcMessage” is declared as a partial method. This means that it doesn’t contain an implementation, but the “WhoAmI” method can still call it.

The actual implementation of the code that decides on the message is unique to the two apps.

So now the “Identity” class now looks like this:

using System;
using System.Threading.Tasks;
using Windows.UI.Popups;

namespace UsingPartials
{
    public partial class Identity
    {
        string _message;

        public async Task WhoAmI()
        {
            CalcMessage();

            var dialog = new MessageDialog(_message);
            await dialog.ShowAsync();
        }

        partial void CalcMessage();    
    }
}

We now create a new class file in the Windows Store app:

namespace UsingPartials
{
    public partial class Identity
    {
        partial void CalcMessage()
        {            
            _message = "I'm a Windows Store App!";
        }
    }
}

And another one in the Phone app:

namespace UsingPartials
{
    public partial class Identity
    {
        partial void CalcMessage()
        {
            _message = "I'm a Windows Phone App!";
        }
    }
}

Now the implementation of CalcMessage can be different for both platforms, but other code can still be shared in the shared project version of Identity.cs.

We also now don’t have any conditional directives in use.

If we only have one or two of these conditional directives, then it’s probably easier to just keep them as is, but if there are lots of them and it’s making readability harder then partials may be a useful alternative.

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

Getting Started Building a Universal Windows App

Universal Windows apps promise to enable the sharing of app code between Windows 8.1 Store apps and Windows Phone 8.1 apps.

In this demo, we’ll create a simple app and see how much work we can share between the two platforms. The sample code and design is probably not how we’d choose to implement a final solution but it will suffice for demo purposes.

Getting Started

Install Visual Studio 2013 Update 2.

Create a new project, head to the Visual C#, Store Apps, Universal Apps; choose the Blank App (Universal Apps) as the following screenshot shows. Name the app “Speechless”.

Visual Studio Universal App Create New Project

Once the solution is created, there will be 3 projects, one for Windows Store, one for Windows Phone, and a third project where we can put all the code we want to share between the two apps.

Universal App Solution

Creating a Shared Class

First off let’s create a class that we can share between apps:

solution screenshot

using System.Collections.Generic;

namespace Speechless
{
    static class Messages
    {
        public static IEnumerable<string> Greetings
        {
            get
            {
                yield return "Hello";
                yield return "Yo!";
                yield return "What's up?";
                yield return "Good day sir!";
            }
        }
    }
}

This just gives a few greetings that the user can choose from. Because this class was added in the Speechless.Shared project, it can be used from both apps.

So we could just go and create some XAML in each app and use this class, but let’s see if we can actually share XAML between apps to further reduce effort.

Creating a shared User Control

In the Speechless.Shared project, add a new item of type User Control called “ChooseGreatingControl.xaml”.

Add some XAML:

<UserControl
    x:Class="Speechless.ChooseGreatingControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Speechless"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"    
    Width="300">
    
    <Grid>
        <StackPanel>
            <ComboBox Name="GreetingChoice" ></ComboBox>
            <Button Name="SayIt" Click="SayIt_OnClick">Speak</Button>
        </StackPanel>
    </Grid>
</UserControl>

This gives the user a ComboBox to choose which greeting to speak.

In the code behind:

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

namespace Speechless
{
    public sealed partial class ChooseGreatingControl : UserControl
    {
        public ChooseGreatingControl()
        {
            this.InitializeComponent();

            GreetingChoice.ItemsSource = Messages.Greetings;

            GreetingChoice.SelectedIndex = 0;
        }

        private async void SayIt_OnClick(object sender, RoutedEventArgs e)
        {
        }
    }
}

Here we’re just wiring up the ComboBox items to those in the Messages class and setting the default selected item to the first one.

Next let’s try to add some code to do some text to speech:

private async void SayIt_OnClick(object sender, RoutedEventArgs e)
{
    var sayWhat = GreetingChoice.SelectedValue as string;

    var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();

    Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(sayWhat);

    var mediaElement = new MediaElement();
    mediaElement.SetSource(stream, stream.ContentType);
    mediaElement.Play();
}

So now we have some UI XAML and some code, let’s see how easy it is to share this user control between the two apps.

Using the Same User Control from Both Windows Store and Windows Phone Apps

In the MainPage.xaml of the Windows Store app project, let’s add an instance of the user control:

<Page
    x:Class="Speechless.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Speechless"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <local:ChooseGreatingControl></local:ChooseGreatingControl>
    </Grid>
</Page>

Let’s go and do the same for the Windows Phone app:

<Page
    x:Class="Speechless.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Speechless"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <local:ChooseGreatingControl></local:ChooseGreatingControl>
    </Grid>
</Page>

Running the Apps

So lets try running now, first the Windows Store app (which is selected as the default start-up app), so F5…

Windows Store app screenshot

Clicking the Speak button works, and speaks outputs the selected greeting.

So let’s try the Windows Phone app, select it as the start-up app and hit F5…

System.UnauthorizedAccessException

This is because we need to add the Microphone capability to the Windows Phone app, once this is done the app runs and works as expected:

Windows Phone screenshot

Conclusions?

This is pretty cool. Having written an app in the past  that targets both Windows Store and Windows Phone this shared project makes things SO much easier – no linked file frustrations.

The next app I start writing (whether Store or Phone) I’ll use this Universal template just so if I want to port it to the other platform it will be ready to go.

It’s going to be interesting mixing this approach with Portable Class Libraries as well. Also a framework such as MVVMLight.

If there is code in the Shared project that only applies to either Store or Phone, we can use the predefined directives:

#if WINDOWS_APP
            // Store only app specific code here
#else
            // Phone only app specific code here
#endif

Whilst I don’t know what the plans are regarding Xbox One, it would be cool to have an Xbox One app store and we could just add an “Xbox One App” to our Universal Apps solution, build, and have the same app with most of the code and UI shared between Windows Store, Windows Phone, and Xbox One.

Exciting times!

SHARE:

A Feature Based Approach to Organising Test Code in BDDfy and Other Testing Frameworks

We want our test code to be as high quality as possible, this means smaller amounts of code duplication, reasonably easy to find where things are in Visual Studio, etc.

One possible organization structure is to think in terms of the individual features in the application. The approach you take will probably depend on the complexity and size of the test suite, system under test, etc. Because BDDfy is "just code" we can use all the normal techniques of composition and inheritance that we'd use in our production code to get to the right level of code reuse and organization for the application we're testing.

Organisation by Feature

Organising by feature enables a reasonable amount of code reuse between test scenarios and it also helps to think user- or business-first rather than code/implementation first.

So for example, if we’re using BDDfy to test a banking application we might have the following features:

  • Login
  • Logout
  • Move Money
  • Pay Bills
  • View Transactions
  • etc

Each of these features contains a number of scenarios, for example Login would probably contain scenarios for successful login, bad password, locked out account, 2 factor login, etc.

In Visual Studio we could create folders in the test project to represent and organize these features as the following screenshot illustrates.

Visual Studio feature folders

 

So a (cut down) Login BDDfy story class could look like the following code:

namespace Tests.Login
{
    [TestFixture]
    [Story(AsA="As a Customer",
        IWant = "I want to login",
        SoThat = "So that I can manage my accounts and money")]
    public class CustomerLogin
    {
        [Test]
        public void LoginSuccess()
        {
            this.Given(x => GivenIAmOnTheLoginScreen())
                .And(x => x.AndIHaveEnteredMyUsername())
                .And(x => AndIHaveEnteredMyPassword())
                .When( x=> WhenIChooseLogin())
                .Then(x => ThenIShouldBeLoggedIn())
                .BDDfy<CustomerLogin>();
        }

        public void GivenIAmOnTheLoginScreen()
        {
        }

        public void AndIHaveEnteredMyUsername()
        {
        }

        public void AndIHaveEnteredMyPassword()
        {
        }

        public void WhenIChooseLogin()
        {
        }

        public void ThenIShouldBeLoggedIn()
        {
        }
    }
}

Now for arguments sake, say we have a Navigation story class that represents how the user should be able to move around the applications features.

We could reuse the individual given/when/then methods in CustomerLogin but we don’t want our navigations scenarios to be bloated, we want them to represent the essence of the scenario with the right level of detail.

So the first thing we could do is to create a “step aggregation” method in CustomerLogin as follows:

public void GivenIHaveLoggedIn()
{
    GivenIAmOnTheLoginScreen();
    AndIHaveEnteredMyUsername();
    AndIHaveEnteredMyPassword();
    WhenIChooseLogin();
}

This method simply re-uses the existing steps but aggregates them into a method we can call from the navigation tests:

using NUnit.Framework;
using TestStack.BDDfy;
using TestStack.BDDfy.Core;
using Tests.Login;
using TestStack.BDDfy.Scanners.StepScanners.Fluent;

namespace Tests
{
    [TestFixture]
    [Story(AsA="As a Customer",
        IWant = "I want to navigate around the site",
        SoThat = "So that I can get to the features I want to use")]
    public class Navigation
    {
        [Test]
        public void NavigateToMoveMoney()
        {
            var custLogin = new CustomerLogin();

            this.Given(x => custLogin.GivenIHaveLoggedIn())
                .When(x => WhenChooseGotoMoveMoney())
                .Then(x => ThenIShouldBeTakenToTheMainMoveMoneyScreen())
                .BDDfy<Navigation>();
        }

        private void ThenIShouldBeTakenToTheMainMoveMoneyScreen()
        {            
        }

        private void WhenChooseGotoMoveMoney()
        {            
        }
    }
}

So here were are making use of this aggregate method from the CustomerLogin feature class.

If we don’t need to represent the fact that the customer is logged-in in the report and all the tests in the class assume a logged-in user, we could use some (e.g. NUnit) test setup code that logs the user in but doesn’t get reported.

The HTML output of this looks as follows:

BDDfy HTML report

 

While in these examples we have a single story class for the feature (e.g. CustomerLogin) once we start adding scenarios (and steps) this single story class might become too bloated. If this is deemed a problem then we can break it out into sub features/stories or if it’s applicable we could use inheritance to hold common given/when/then steps. The individual story classes relating to the customer login feature would all inherit this base class. We probably however, do not want multiple levels of nested inheritance in our stories as this may make maintenance and discoverability harder.

To see more of what BDDfy can do check out my Building the Right Thing in .NET with TestStack Pluralsight course, head on over to the documentation, or check it out on GitHub

SHARE:

Testing ASP.Net MVC Controllers with FluentMVCTesting

FluentMVCTesting facilitates the writing of tests against MVC controllers in a fluent way.

FluentMVCTesting is available via NuGet: Install-Package TestStack.FluentMVCTesting

There’s a number of things that FluentMVCTesting can help to test such as:

  • A controller action returns the correct view
  • A controller action returns the correct HTTP status
  • A controller action returns an empty result
  • A controller action returns a view if there are model errors
  • A controller action returns a view with the correct model data
  • A controller action should redirect to a Url / Route / Action

It’s also not tied to a specific testing framework, so it can be used with NUnit, xUnit.net, MSTest, etc.

Examples

var sut = new ExampleController();

sut.WithCallTo(x => x.Show()).ShouldRenderView("Orders");

The preceding test code is testing the ExampleController. It is testing that when the Show() action is called then the Orders view is rendered.

The following code checks that an expected HTTP status is returned.

var sut = new ExampleController();

sut.WithCallTo(x => x.MakeAnError())
    .ShouldGiveHttpStatus(HttpStatusCode.InternalServerError);

 

To see more of what FluentMVCTesting can do check out my Building the Right Thing in .NET with TestStack Pluralsight course, check out the documentation, or check it out on GitHub.

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

Business-Readable, Living Documentation with BDDfy

BDDfy enables the creation of tests that, in addition to verifying that the system works correctly, also results in business-readable, living documentation.

Business-readable means that the tests are described in natural language (e.g. English) that the business can read, understand, and ensure that the correct features and functionality is being built.

Living documentation means that the report results directly from the passing or failing of the tests. It’s not a word document somewhere on a shared drive or SharePoint site that may or may not actually be in sync with what the system actually does.

The Report

Below is an example of what a typical BDDfy HTML report looks like (there is a “metro” inspired report coming in V4). There’s also the ability to output the test report in markdown.

BDDfy HTML report

Notice that it’s not code-centric output, but rather business-centric.

Here the two test scenarios are grouped into a story, but they don’t have to be.

The underlying test framework that is used to execute the test doesn’t matter – you could use NUnit, xUnit.net, MSTest, etc.

The Test Code

The tests that produce this report could be configured in BDDfy in a couple of ways. There is a reflective style that uses methods that following a specific naming convention. There is also the fluent style.

The test code to produce this report looks like the below (we are using NUnit in this example).

using NUnit.Framework;
using TestStack.BDDfy;
using TestStack.BDDfy.Core;
using TestStack.BDDfy.Scanners.StepScanners.Fluent;

namespace BDDfyDemo
{
    [TestFixture]
    [Story(AsA = "As a customer",
        IWant = "I want my order total to add up correctly",
        SoThat = "I'm not overcharged for my goods")]
    public class OrderTotalCalculatorTests
    {
        [Test]
        public void MultipleOrderedItemsTotals()
        {
            this.Given(x => GivenIHaveAddedItemsToMyCart())
                .When(x => WhenICheckout())
                .Then(x => ThenTheOrderTotalExcludingTaxShouldBeCorrect())
                .BDDfy<OrderTotalCalculatorTests>();
        }

        [Test]
        public void SalesTaxAdded()
        {
            this.Given(x => GivenIHaveAddedItemsToMyCart())
                .When(x => WhenICheckout())
                .Then(x => ThenTheSalesTaxShouldBeCorrect())
                .BDDfy<OrderTotalCalculatorTests>();
        }

        public void GivenIHaveAddedItemsToMyCart()
        {
            // test code
        }

        public void WhenICheckout()
        {
            // test code
        }

        public void ThenTheOrderTotalExcludingTaxShouldBeCorrect()
        {
            // test code
        }

        public void ThenTheSalesTaxShouldBeCorrect()
        {
            // test code
        }

    }
}

Here there are a couple of NUnit tests defined – the methods with the [Test] attribute applied to them.

Within these test methods the BDDfy fluent style is being used to define the different steps in the test scenarios.

The “given” phase sets up the initial context or state of the thing being tested. The “when” phase acts upon the system to produce some change. The “then” phase is typically where we have assert code, it’s in this phase that the resulting state of the system is checked.

Notice how the individual method names appear in the test report in a nice business-readable way.

 

There’s a lot more to BDDfy, such as data-parameterised tests and a whole heap of customisation and configuration options. To see more of what BDDfy can do check out my Building the Right Thing in .NET with TestStack Pluralsight course, head on over to the documentation, or check it out on GitHub.

SHARE:

Beyond the Compiler with ConventionTests

We often have conventions in our code. For example all DTOs/entity/etc. classes should be in a specific namespace, or the name of certain types of class should end with a given word. Another example, we may need to make sure that all classes (or those in a specific namespace) contain all-virtual members.

These kind of things are conventions that the team may agree to but the compiler won’t pick up as build errors or warnings. The code may still be completely valid C# even though it violates a convention.

ConventionTests is a brilliant idea (and it’s ideas like this that keep me loving programming) allows us to write tests to verify these conventions, conventions that the compiler cannot verify.

Installation

Simple installation via NuGet into your test project: PM> Install-Package TestStack.ConventionTests

Simple Usage

Using whatever testing framework you prefer (xUnit.net, NUnit, etc.) create a test method.

these kind of things are conventions that the team may agree to but the compiler won’t pick up

In this method, the first thing to do is to select all the types in the production code that we want to check against a convention.

We can do this with code such as:

var typesToCheck = Types.InAssemblyOf<SomeClass>();   

Here the Types.InAssemblyOf method is being used to find which assembly contains the class called SomeClass. Using this overload, all of the types in the assembly will be selected, however there are other overloads that allow the returning of types in a given namespace.

The next step is to create an instance of one of the out-of-the-box conventions.

var convention = new AllClassesHaveDefaultConstructor();

This convention checks that all the selected types have a default constructor defined.

Now we have the list of types we want to check, and a convention to check them against.

To actually perform the check, we use the Convention.Is method:

Convention.Is(convention, typesToCheck);

If any of the classes selected in typesToCheck don’t have a default constructor then an exception will be thrown (with some useful info in it) and the test will fail.

You can see some of the other out-of-the-box conventions on the GitHub site, you can also write your own custom conventions.

 

ConventionTests is one of the tools in the TestStack suite. To learn more about ConventionTests and the other TestStack tools, checkout out my Building the Right Thing in .NET with TestStack Plurasight course.

SHARE:

FeatureToggle Version 2 Released

FeatureToggle logo

Version 2 of my open source feature toggling .Net library has just been released to NuGet.

V2 introduces a number of breaking changes – see release notes. It also include binary Windows Store DLLs as opposed to code-only.

Version 2 will form the base for new feature in the future.

FeatureToggle.Core has been introduced as a portable class library.

For more details see the documentation, or the examples.

SHARE:

Building the Right Thing with TestStack

My newest Pluralsight course was just released today: Building the Right Thing in .NET with TestStack.

TestStack is a suite of tools to help the team build better software.

The super-friendly members of TestStack are:

  • Jake Ginnivan
  • Krzysztof Koźmic
  • Mehdi Khalili
  • Michael Whelan
  • Robert Moore

TestStack consists of the following tools:

  • BDDfy: turn tests into business readable, living documentation
  • Seleno: automated UI web testing with strongly-typed page object models
  • FluentMVCTesting: unit test ASP.NET MVC controllers using fluent syntax
  • White: automated UI testing for Win32 based rich client applications
  • ConventionTests: write tests to check coding conventions are being adhered to

To get started learning the TestStack tools check out the Pluralsight course, the documentation site, or learn how to contribute to the TestStack project.

SHARE:

Creating a Windows Store App NuGet Package for ARM, x86 and x64

It’s possible to create a NuGet package from a Window Store class library project that contains 3 different DLLs, one for each of the platform types: ARM, x86, and x64.

When the NuGet package is included in a Windows Store app, if the build platform for the app is changed to ARM for example, if the DLL that’s in the NuGet package was built for x86, there will be a build error.

The secret to making this happen is to use the “build” folder in your NuGet package.

This “build” folder sits alongside the lib and content folders.

If we are creating a package to be used in Windows 8.1 Store apps, this build folder will contain a sub folder called “netcore451”. It’s in this folder where the magic happens.

screenshot of file structure

This is a screen shot of the contents of the build folder. (It’s from my open source FeatureToggle library). Notice the platform specific folders. In each of these folder we place the relevant DLL, compiled for each platform.

screenshot of file structure

We also place the x86 version in the lib folder (apparently this can stop Visual Studio/designer from complaining.)

screenshot of file structure

Back to the build folder.

Notice the FeatureToggle.targets file.

For the following to to work it needs to be named the same as the package ID, in the case the NuGet package id is “FeatureToggle”.

The contents of this file allows NuGet to add to the .csproj file in the app that the package is installed into.

The contents of this .targets file look like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="PlatformCheck" BeforeTargets="InjectReference"
    Condition=" ( ('$(Platform)' != 'x86') AND ('$(Platform)' != 'ARM') AND  ('$(Platform)' != 'x64') )">
    <Error  Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' 
                     platform. You need to specify platform (x86 / x64 or ARM)." />
  </Target>
  
  <Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">

    <ItemGroup Condition=" '$(Platform)' == 'x86' or '$(Platform)' == 'x64' or '$(Platform)' == 'ARM'">
      <Reference Include="FeatureToggle.WindowsStore">
        <HintPath>$(MSBuildThisFileDirectory)$(Platform)\FeatureToggle.WindowsStore.dll</HintPath>
      </Reference>
    </ItemGroup>

  </Target>
</Project>

When the NuGet package is installed it will change the host apps .csproj file and add in the logic contained in this targets file. Now, before the app is built, the current build platform will be examined and the reference will be changed so that the relevant platform binary is used from either the ARM, x86, or x64 folder in our NuGet build folder. If the platform is not set to either ARM, x86, or x64 then the build will error with a message saying that a specific platform needs to be built –as opposed to AnyCPU for example.

The .targets file above is based on this MSDN article by Sebastien Pertus. The article also discusses packaging WinRT components.

SHARE: