0 Comments

nuget

See how you can easily create NuGet packages to publish cross platform C# libraries that allow to integrate platform specific code in your Portable Class Library (PCL) based Projects. In a former post you can read about how to create a cross platform library and see how the library has to be consumed by the e.g. app consuming the library. This post builds up on where that last post left off and shows how we can use the library providing the OS version number in a NuGet package. So the package we want to create has the following structure:

 

  • OSVersion.Core
  • OSVersion.UWP
  • OSVersion.Droid
  • OSVersion.iOS

 

Our goal is to generate a single NuGet package which can be added to any of the above named platforms.

Note: Though this post focuses on the platforms Universal Windows Platform (UWP), Android and iOS the approach can be easily extended to support additional platforms such as .Net, Silverlight et al.

Creating the package definition

First of all we will need to install the NuGet command line tool. Make sure that you add it to your PATH. After it is added to your path you can execute the NuGet commands with PowerShell. To create a NuGet package you need a nuspec file which you can generate by executing the command):

nuget spec

The location of the nuspec file does not really matter – I tend to have it in my root directory i.e. where the Solution file is. If you open the file in your lightweight editor of choice, you can edit the package specification to your gusto or for our sample somewhat like this:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>OSVersion</id>
    <version>1.0.0.3</version>
    <title>OS Version</title>
    <authors>Mark Allibone</authors>
    <owners>Mark Allibone</owners>
    <!--<licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>-->
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Get the OS version for your UWP, Android or iOS app.</description>
    <releaseNotes>This is the initial release.</releaseNotes>
    <copyright>Copyright 2015</copyright>
    <tags>OSVersion</tags>
  </metadata>
  
  <files>
    <file src="OSVersionAPI\bin\Release\OsVersionAPI.Core.dll" target="lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10+UAP10\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI\bin\Release\OsVersionAPI.Core.pdb" target="lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10+UAP10\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI\bin\Release\OsVersionAPI.Core.xml" target="lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10+UAP10\OsVersionAPI.Core.xml" />
    
    <file src="OSVersionAPI.UWP\bin\Release\OsVersionAPI.Core.dll" target="lib\UAP10\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI.UWP\bin\Release\OsVersionAPI.Core.pdb" target="lib\UAP10\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI.UWP\bin\Release\OsVersionAPI.Core.xml" target="lib\UAP10\OsVersionAPI.Core.xml" />
    
    <file src="OSVersionAPI.Droid\bin\Release\OsVersionAPI.Core.dll" target="lib\monoandroid1\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI.Droid\bin\Release\OsVersionAPI.Core.pdb" target="lib\monoandroid1\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI.Droid\bin\Release\OsVersionAPI.Core.xml" target="lib\monoandroid1\OsVersionAPI.Core.xml" />
    
    <file src="OSVersionAPI.iOS\bin\iPhone\Release\OsVersionAPI.Core.dll" target="lib\xamarin.ios10\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI.iOS\bin\iPhone\Release\OsVersionAPI.Core.pdb" target="lib\xamarin.ios10\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI.iOS\bin\iPhone\Release\OsVersionAPI.Core.xml" target="lib\xamarin.ios10\OsVersionAPI.Core.xml" />
  </files>
</package>

Beware of the target folder structure, these names may seem a bit strange (I’m looking at you Xamarin.Android…) but these actually have to align with a pattern or else you will run into problems when installing the NuGet package. You can find the target folder names on the NuGet website.

Integrating some Metadata in the NuGet package

You are not required to add the pdb (used for Debugging) or the XML file (Code Documentation for Intellisense) but it is considered best practice and makes the life of the developer using the library easier so I would suggest you follow along with this.

To enable the XML metadata file, right click on a project under Properties, Build you can set the checkmark for XML documentation file. Now you should have an XML file in your build output.

Per default the pdb file should be generated during the build, except for iOS (it’s always you iOS isn’t it…) - anyhow, right click on your project then under Properties, Build, Advanced… set Debug Info to pdb-only.

Beware that these settings are per build Configuration so make sure you set it for Release builds as you usually ship the Release build of a library.

Packing it up

Now all that is left to do is creating the package which we can do with the following command:

nuget pack

After the package is created the next thing to do is make it available for consumption. This means either pushing the package to NuGet or creating your own NuGet repository. Due to the fact, that this here is only a demo I will go with the second option.

Integrating the package in an app

Now we can simply add the OS Version library over the package manager. Notice that we get the same result as in the former blog post but this time the developer using the library will not be required to add the library multiple times to the project i.e. this potential error source no longer exists.

So when we now run the app under UWP we get the following output.

Win10VersionNumber

Note if we would only add the NuGet package to the NativePcl.Core project the output would simply show the stub implementation.

StubVersionNumber

So all the principals that were described in the last post still apply. But adding the library has been greatly simplified.

Conclusion

In this blog post you saw how a cross platform NuGet package can be created which lends itself very well to create cross platform libraries that implement native features which have to implemented differently for each targeted platform. There are many great libraries already out in the wild that use this approach e.g. MVVM Light, SQLite, PCL Storage and many many more.

You can find the sample project on GitHub.

2 Comments

3856456237_f05ebd2602_o

The Portable Class Library (PCL) allows developers to share C#, F# and VB code across multiple devices, platforms and runtime environments such as .Net, Xamarin or Windows Store Apps. In this previous post you can see how you can write portable business logic and integrate it with all the various platforms. But what if you actually want to use something the other way round say the GPS position, file system etc.. What then? This is exactly his post we will look at the following topics:

  • Using Interface Segregation and Dependency Inversion to our favor
    • Interface in the PCL
    • Implementation on the Platform
  • Injecting the implementation at runtime into the PCL
  • Making the resolution of dependencies a breeze with MVVM Light

So lets get to it!

Using Dependency Injection to our favor

Remember SOLID? Well it turns out the last letter stand exactly for the pattern we will be using to solve our “How will I be able to use a platform specific feature cross platform “. The PCL code is platform independent and therefore can be used across multiple platforms, so we want to put near to all of our business logic into a PCL. Further by accessing concrete class implementations via interfaces we can define an Interface in the PCL and create it’s concrete implementation in a platform specific project.

PCLDIOverview

Dependency Injection in action

For example lets say we want to display the current OS version for each platform, this is a very platform specific feature. To access such a information in the PLC we first define an Interface in the PCL that describes the contract the implementation has to implement:

public interface ISystemInformationHandler
{
    string OSVersion { get; }
}

In the concrete platforms we can then inherit the interface and implement the handler which calls the platform specific API (bellow you see the Android implementation):

internal class SystemInformationHandler:ISystemInformationHandler
{
    #region Implementation of ISystemInformationHandler

    //public string OSVersion => System.Environment.OSVersion.ToString();
    public string OSVersion => $"Android {Android.OS.Build.VERSION.SdkInt} {Android.OS.Build.VERSION.Release}";

    #endregion
}

Now in the PCL we can have a class for example a view model that requires the handler to display the information.

public class MainViewModel : ViewModelBase
{
    private readonly ISystemInformationHandler _systemInformationHandler;

    public MainViewModel(ISystemInformationHandler systemInformationHandler)
    {
        if (systemInformationHandler == null) throw new ArgumentNullException(nameof(systemInformationHandler));
        _systemInformationHandler = systemInformationHandler;
    }

    public string OSVersion => _systemInformationHandler.OSVersion;
}

The view model requires as a parameter argument an instance of the IOSVersionHandler interface. So when we create an instance of the MainViewModel in the platform project, we can simply create an instance of interface and pass it into the view model when we create it.

var mainViewModel = new MainViewModel(new SystemInformationHandler());

And receive the following output for e.g. Android:

 

Cross platform Dependency resolution with MVVM Lights

Now resolving all of these dependencies by hand can get very tedious over time. You might have noticed that I’m using MVVM Light which comes with a lightweight Dependency Injection Container called Simple IoC. Lets see how we can use this component to further streamline our cross platform development efforts.

Note:for an introduction to MVVM Light please refer to this blog post for AndroidoriOSto get you started with the basics.

In the PCL we have the ViewModelLocator.cs which defines all of the instances used, but without the platform specific resolution.

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        if (ViewModelBase.IsInDesignModeStatic)
        {
            // Create design time view services and models
            SimpleIoc.Default.Register<ISystemInformationHandler, SystemInformationHandlerStub>();
        }

        SimpleIoc.Default.Register<MainViewModel>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }
}

On each platform we now extend the Locator and register the platform specific classes i.e. resolution for interfaces.

internal class Locator : ViewModelLocator
{
    private static readonly Lazy<Locator> _locator = new Lazy<Locator>(() => new Locator(), LazyThreadSafetyMode.PublicationOnly);
    public static Locator Instance => _locator.Value;

    private Locator()
    {
        SimpleIoc.Default.Register<ISystemInformationHandler, SystemInformationHandler>();
    }
}

Now we can simply request an instance of the view model (MVVM Light per default only creates one instance for each registered class) and use it. In Android this would look something like this in the MainActivity.cs:

[Activity(Label = "PclDISample.Droid", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    #region UI Controls

    private TextView OSVersion => FindViewById<TextView>(Resource.Id.OSVersion);

    #endregion

    private MainViewModel VM => Locator.Instance.Main;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        OSVersion.Text = VM.OSVersion;

        var mainViewModel = new MainViewModel(new SystemInformationHandler());
    }
}

In Windows 10 we can simply set the Datacontext accordingly in XAML:

<Page
    x:Class="PclDISample.UWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PclDISample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{Binding OSVersion}" VerticalAlignment="Center" HorizontalAlignment="Center" Style="{StaticResource TitleTextBlockStyle}"></TextBlock>
    </Grid>
</Page>

As you can see once all is registered with the simple Inversion of Control Container (IoC) of MVVM Light all of the dependency resolution will be performed automatically. If a dependency is missing, an exception will be thrown at runtime (not during compilation), so make sure to test all your views, user controls et al that they load correctly.

Conclusion

In this post you saw how you can use Dependency Injection to provide platform specific features to cross platform code located in the PCL without creating any circular dependency errors. By using interfaces in the PCL and injecting the concrete implementations during runtime we can create thin wrappers that provide platform specific features through a generic defined interface. Finally we saw how we can use MVVM Light to create a more manageable and more manageable dependency resolution with the Simple IoC Locator.

You can find the complete sample on GitHub.

Big thanks to Laurent Bugnion the creator the MVVM Light.

1 Comments

These days if you can write code with C# you can write code for Windows, Linux and OSX, your code can run on Desktop, Server, Mobile or Embedded Devices. So C# runs pretty much everywhere which if you are a C# developer is a great thing! Smile Only little hiccup, even though C# is a standardised language, there are multiple runtimes existing today on which C# runs. This may lead to the assumption of having to rewrite code for every runtime. As the standard .Net C# library can not be reused on a Silverlight runtime, or the new Windows RT runtime, or I think you get the message. But fear not – thanks to the Portable Class Library (PCL) one is able to write code that can be reused over multiple platforms.

Portable Class Libraries

When adding a Portable Class Library (PCL) you will have to choose which platforms you want to use the platform on. The supported platforms have an impact in the functionality the PCL provides without adding any additional libraries (usually via NuGet). You can find a list  of libraries supported by each platform on MSDN.

For this post we will want to reuse our code on the following platforms:

  • Universal Windows App (Windows 10)
  • Classic desktop WPF app
  • iOS (with Xamarin)
  • Android (with Xamarin)

To keep things simple the logic in the app will be creating a list of people. We will even be able to share our view models from the PCL so the only overhead we will be having when creating the app is the actual UI code and wiring up the view models to the actual views. Now in this setup the timesaving's might seem marginal but think about your standard business app and the savings will start to up add up quickly in a major way.

Creating a PCL

Adding the platform specific projects is pretty straight forward. Simply add the corresponding project template to the solution when adding a new project, so I’ll leave it at that and go over to adding a PCL. When adding the PCL a dialog will be opened offering to choose the platforms that shall be supported i.e. can consume the PCL.

Showing Add Portable Class Library Visual Studio dialog with .Net Framework 4.6, Windows Universal 10.0, Xamarin.Android and Xamarin.iOS selected

The iOS and Android option will show up after installing the Xamarin tool chain.

With the platforms chosen we can now start implementing the “business logic” which in our case is a simple generator that we invoke, called PersonService.cs:

public class PersonService
{
    public async Task<IEnumerable<Person>> GetPeople(int count = 42)
    {
        var people = new List<Person>(count);
        // In case of large counts lets be safe and not run this on the UI thread
        await Task.Run(() =>
        {
            for (int i = 0; i < count; ++i)
            {
                people.Add(new Person{FirstName = NameGenerator.GenRandomFirstName(), LastName = NameGenerator.GenRandomLastName()});
            }
        });

        return people;
    }
}

To present our data to the UI we will use the MVVM pattern.

Adding MVVM Light

When using MVVM in a project (which is like always for me Winking smile) I prefer using MVVM Light. MVVM Light can be added by simply installing a NuGet package:

PM> Install-Package MvvmLightLibs

As we will access the view models from the platforms make sure to add the MVVM Light libraries also to the platform specific code bases.

Now we can add the view model MainViewModel.cs that will hold the list of people we will display.

public class MainViewModel:ViewModelBase
{
    private readonly IPersonService _personService;

    public MainViewModel(IPersonService personService)
    {
        if (personService == null) throw new ArgumentNullException(nameof(personService));
        _personService = personService;
        if (IsInDesignMode)
        {
            People = new ObservableCollection<Person> {new Person{FirstName = "Doctor Who"}, new Person {FirstName = "Rose", LastName = "Tyler"}, new Person {FirstName = "River", LastName = "Song"} };
        }
        else
        {
            People = new ObservableCollection<Person>();
        }
    }

    public ObservableCollection<Person> People { get; set; }

    public async Task InitAsync()
    {
        var people = await _personService.GetPeople();
        People.Clear();
        foreach (var person in people)
        {
            People.Add(person);
        }
    }
}

Next we still need to configure the ViewModelLocator.cs, which allows us to easily manage dependencies.

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<IPersonService, PersonService>();
        SimpleIoc.Default.Register<MainViewModel>();
    }

    public MainViewModel MainViewModel => SimpleIoc.Default.GetInstance<MainViewModel>();
}

So now we have all of our cross platform code setup. Let’s get it running on our desired targets.

The platforms

On the platforms we can simple reference the PCL like any other library we might use and access the features. On our platforms we will have to do the following steps:

  1. Create the UI
  2. Hook up theViewModelLocator.cs
  3. Wire up the view model to the view

Let’s do these steps for the Universal Windows App.

Universal Windows App (UWA)

For the view we will simply add a ListView to the MainPage.xaml:

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

    <ListView ItemsSource="{Binding People}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding FirstName}"/>
                <TextBlock Text="{Binding LastName}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Page>

Under Windows (this is also true for WPF) MVVM Light really integrates really nicely. The Locator we can simply add to the App.xaml:

<Application
    x:Class="PclSample.UWA.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PclSample.UWA"
    RequestedTheme="Light">
    <Application.Resources>
        <vm:ViewModelLocator x:Key="Locator" xmlns:vm="using:PclSample.Core" />
        <ResourceDictionary />
    </Application.Resources>
</Application>

This allows us to access properties from the ViewModelLocator.cs class within our view(s) i.e. MainPage.xaml. So the next step would be wiring up the view model to the views DataContext, which will populate the view:

<Page
    x:Class="PclSample.UWA.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PclSample.UWA"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    DataContext="{Binding Source={StaticResource Locator}, Path=MainViewModel}"
    mc:Ignorable="d">

    ...
</Page>

Now all is set and we can enjoy the view of our light weight UWA.

Screenshot of the UWA running in the Windows 10 Mobile Emulator

Windows Presentation Foundation (WPF)

Following the same steps as in the UWA in a WPF app will lead to the same result.

Shows sample app running in as a WPF desktop application

So we can reuse all of our business logic from one Microsoft client development model to an other one. Isn’t that just great? Smile But wait there is more. We can take the C# code outside of the Microsoft Ecosystem. With for example Xamarin we can reuse our C# code on iOS and Android.

iOS

Under iOS the UI is usually created in a designer (similar to Windows Forms) so there is not much code to show. We add the ListView equivalent from iOS a UITableView to a page and give it a name, in this sample PeopleTableView.

Showing iOS Designer and where the name of the UITableView is set.

Setting up the ViewModelLocator.cs is not quite as elegant when we leave the Microsoft platforms but then again it is done just as easily. In the AppDelegate.cs which is the start up point of every iOS app we simply create an Instance of the ViewModelLocator.cs and store it in a property. The property then can be accessed throughout the iOS app. The Wiring up of the view model is done in the ViewController.cs which is linked to the view that we setup earlier:

public partial class ViewController : UIViewController
{
    ObservableTableViewController<Person> _tableViewController;

    public ViewController (IntPtr handle) : base (handle)
    {
    }

    private MainViewModel Vm => Application.Locator.MainViewModel;

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        // Perform any additional setup after loading the view, typically from a nib.

        _tableViewController = Vm.People.GetController(CreatePersonCell, BindPersonCell);
        _tableViewController.TableView = PeopleTableView;
    }

    public override async void ViewWillAppear (bool animated)
    {
        base.ViewWillAppear (animated);
        await Vm.InitAsync();
    }

    public override void DidReceiveMemoryWarning ()
    {
        base.DidReceiveMemoryWarning ();
        // Release any cached data, images, etc that aren't in use.
    }

    UITableViewCell CreatePersonCell (Foundation.NSString reuseId)
    {
        var cell = new UITableViewCell(UITableViewCellStyle.Default, null);
        return cell;
    }

    void BindPersonCell (UITableViewCell cell, Person person, Foundation.NSIndexPath path)
    {
        cell.TextLabel.Text = person.FullName;
    }
}

Now all that is left to do for us is again fire up the iOS Simulator to verify all is correct and there we have it, the same C# code we used for our WPF and UWA apps is now running under iOS:

iphone

Android

What we did under iOS we can also replicate under Android. Though not part of the Microsoft eco system the model should be more familiar if you have written WPF, Modern Apps (and all the other fancy names they had i.e. Universal Apps). Under Resources/Layouts there is the main.axml which is a (Application) XML file we can edit to tell the Android OS how to render the UI. Sounds a bit like XAML right? And the concepts do overlap in some parts too. Adding a ListView to the XML and set the id of the element which will allow us to access it later on:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/PeopleListView" />
</LinearLayout>

Again we will have to setup the locator. Under Android there is no fixed setup point, so we will use a static class Locator.cs and property which we will access from the Android app:

internal static class Locator
{
    private static readonly Lazy<ViewModelLocator> _locator = new Lazy<ViewModelLocator>(() => new ViewModelLocator());
    public static ViewModelLocator Instance => _locator.Value;
}

Wiring up the view model is done in the MainActivity.cs, which you can think of as the code behind/ViewController equivalent. I wrote about this binding in more detail in a former blog post which you can find here.

[Activity(Label = "PclSample.Droid", MainLauncher = true, Icon = "@drawable/icon")]
internal class MainActivity : Activity
{
    protected override async void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        await Vm.InitAsync();

        // Get our button from the layout resource,
        // and attach an event to it
        PeopleListView.Adapter = Vm.People.GetAdapter(GetPersonView);
    }

    public ListView PeopleListView => FindViewById<ListView>(Resource.Id.PeopleListView);

    private MainViewModel Vm => Locator.Instance.MainViewModel;

    private View GetPersonView(int position, Person person, View convertView)
    {
        View view = convertView ?? LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);

        view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = person.FullName;

        return view;
    }
}

Note that the id we previously set allows us to retrieve the UI control.

At this point we can start up the Android Emulator and just to have mentioned it Visual Studio 2015 provides a great Android Emulator – way better then the stock emulator! And once again we can see the app is running reusing the C# code we tucked away in our PCL.

Shows app running in the Android Emulator

Conclusions

In this blog post we saw how one can share C# code with a Portable Class Library (PCL). The PCL can be included in all major C# stacks .Net, UWP, Silverlight, Xamarin etc. and though the capabilities in the PCL are more limited then a standard .Net library it does allow to share code from a legacy WPF/Win Forms app to a mobile application.

PCLs can be extended by installing further NuGet packages such as storage, network access and many more. The PCL has been around for a couple of years now and has proven itself to be a valuable component when writing cross platform applications.

The entire sample can be found on GitHub.

0 Comments

title_thumb2

On the 6. October 2015 Microsoft introduced it’s new devices all destined to run Windows 10.

The first Device was the HoloLenswhich was demoed with a immersive game experience showing how HoloLens can integrate the furniture of your living room in the game. Plus the HoloLens should start to be available next year for developers for 3000$, so far only US availability has been announced, but my hopes are still high that it will reach Europe and other countries outside of the US soon after that.

band2_thumb

After the HoloLens the new Microsoft Band 2 was introduced. The specs of the band leaked before the event and they seem to be have quite spot on. The new band has a curved display, looks sleeker and has an additional 11th sensor (a barometer) which allows it to track elevation/steps. The band is focused on sport and tracking the users physical activities. The data is stored in the Microsoft health service which allows the user to analyse all of his activities i.e. golf, sleep, running and many more. The Data is stored as usually done with these services in the cloud and not on the devices of the user.

Further Microsoft partnered up with quite a few companies to ensure the band will have apps that provide the user with additional apps and notifications right at your wrist.

Windows Mobile

Lumia-950_thumb2

With the Lumia 950 and 950 XL Microsoft finally has introduced two flagship phones which has been overdue and long awaited. Since the Lumia Icon/930 and Lumia 1520 which they are replacing have been on the market for years(!). The new Lumias keep true to their heritage of providing great Cameras (20MP incl. image stabilization), great displays and the obligate bump in battery size. Further the following specs stick out:

  • Expandable storage via SD-Card
  • 3 GB RAM
  • Snapdragon 808 processors
    • 6-Cores
    • 8-Cores XL
  • USB-C connector

The new USB-C connector allows an ease of use and greater bandwidth but there is more, with the new phones Microsoft introduces Continuum. With an additional accessory called a Microsoft Display Dock you can plug in your phone to a monitor, keyboard and mouse allowing you to control desktop applications such as Word, PowerPoint etc.. The apps that can be used will be based on the Universal Windows Platform (UWP) which allows developers to adopt for different screen sizes. So when the app provides resolutions for phone and desktop factors the same phone app will be displayed differently and allow the user to harness the full power of a desktop setup such as using a mouse and a real keyboard.

While connected to the Microsoft Display Dock the phone will still be available as a phone, meaning you can make calls, write and receive texts etc.. So it isn’t just simply projecting the screen of the phone to another display but it actually will bring up a (limited) Windows 10 desktop experience which I see some very interesting scenarios arising and allows you to use the phone as a PC! Smile

While the Lumia 950 und Lumia 950 XL are high end phones Microsoft also introduced the new Lumia 550 which will provide a cheaper alternative without the Continuum though but still providing quite some bang for the buck.

Surface Pro 4

sp4_thumb4

The Surface Pro 4 is the expected update of the Surface Pro 3. While keeping the dimensions of the SP3 the SP4 comes with the latest Intel chipset, up to 16 GB RAM and 1 TB hard drive. These specs are a great bump and will allow to run Virtual Machines easily from your SP4. Keeping the dimensions will mean that all the external hardware accessories for the SP3 will work with a SP4 and vice versa. If you are the proud owner of a SP3 and have a dock. You will be able to simple reuse the dock for the SP4. All the hardware released for the SP4 also works for the SP3.

While keeping the overall dimensions the SP4 comes with a greater resolution which comes to the cost of the bezel. The screen now comes at 12.3 inches and sports 2736 x 1824 resolution which results in a really high res display at 267 pixels per inch (ppi).

Type cover

The new type cover comes with a full keyboard layout, 40% larger track pad and there will even be versions with a biometric finger reader. Real world testing will prove how much better it is overall but a full size keyboard layout surely sounds lovely.

Pen

The pen has been overhauled slightly. The backend tip now not only is the OneNote button but also serves again as rubber as it was the case with the SP1 & 2 pens. The pen tip can be interchanged which will allow artistic and design folks to choose individual brushes simply by changing the tip and sport the physical feel.

pen_thumb1

Another great plus is that the pen now attaches magnetically to the Surface, so no more after thought latches needed. I really like this additional feat as I never grew warm to the latch (in my case still in the original packaging…).

Docking Station

surface_dock_thumb3

The new docking station no longer requires you to place the Surface Pro into it. It is an elegant little box that you can attach via the power connector. The new Docking Station provides gigabit Ethernet, two display ports, four USB 3.0 ports, audio out and of course power to the Surface Pro 4 and can be used with the Surface Pro 3.

 

(One more thing) Surface Book

The biggest surprise (very positive surprise) is the Surface Book. Other then the SP4 it comes with a Keyboard dock that can be removed at the push of a button. The design looks very sleek and though it does not close fully it resembles pretty much a laptop. In the keyboard half of the Surface Book are additional batteries and a custom made NVidia graphics card. So it has no problems stemming graphically intensive work such as 3D design or games.

surfacebook_thumb2

Being able to remove the tablet results in a light weight and really thin tablet (the USB, Power and display ports are all in the keyboard part). The tablet has the form factor of an A4 paper so it should give you known dimensions and with a pen will allow you to get a great note, drawing, etc. paper.

All accessories from the SP4 are compatible with the Surface Book. But you will not be able to stick it into a SP3 docking station. But it will go nicely with the new SP4 docking station which is less bulky and just as clean.

The take away

Microsoft gave an awesome presentation and highlighted a lot of great features that they usually just seemed to forget to bring forward to the crowd. During the great presentation they highlighted the future with HoloLens, the next step for Windows Phone which will be renamed to Windows Mobile with Windows 10 and the great line up of Surface hardware.

With the new hardware I am sure the surface will continue to grow and expand in a market that is looking how to integrate tablets for the workforce which requires additional input compared to a candy crush app.

The phone hardware finally serves again the users that do want to spend some money for a device and brings some great power user features to the I-want-to-get-stuff-done minded people out there.

I personally can’t wait to get my hands on the new hardware and give it a run especially the phones continuum mode and the new Surface Book are looking very nice and I already fear the impact on my bank account Winking smile

0 Comments

TitleImage

Writing Unit, Component and Integration tests allows to test functionality of software modules. In other words letting developers sleep tightly without worries at night. These tests run against certain parts of the code verifying the logic and interaction between modules of the app. All this is usually performed on the developers machine powered by a beefy processor and often unheard amount of RAM when it comes to mobile devices. Wouldn’t it be great if we could get a bit closer to the real thing? Well we can…

In this blog post we will look at how we can run xUnit.net tests on a device. The app will be a Xamarin(.Forms) app, which consists of three platform projects and a shared Portable Class Library which can be used to write logic that can be consumed on every platform.

Setting up xUnit.net

The typical xUnit.net tests are created in a standard .Net library. All that is required is the xUnit.net NuGet package:

PM> Install-Package xunit -Version 2.0.0

Now we can create start writing unit tests, for this blog post let’s stick to the basic calculator example in the BasicMathServiceTest.cs:

public class BasicMathServiceTest
{
    private BasicMathService _basicMathService;

    public BasicMathServiceTest()
    {
        _basicMathService = new BasicMathService();
    }

    [Fact]
    public void Add_GivenTwoNumbers_TheSumIsReturned()
    {
        var x = 35;
        var y = 7;
        var expectedResult = 42;

        var result = _basicMathService.Add(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void Subtract_GivenTwoNumbers_TheSubtractedResultIsReturned()
    {
        var x = 456;
        var y = 123;
        var expectedResult = 333;

        var result = _basicMathService.Subtract(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void Mulitply_GivenTwoNumbers_TheResultIsReturned()
    {
        var x = 2;
        var y = 2;
        var expectedResult = 4;

        var result = _basicMathService.Multiply(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void Divide_GivenTwoNumbers_TheSumIsReturned()
    {
        var x = 848;
        var y = 8;
        var expectedResult = 106;

        var result = _basicMathService.Divide(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void TheFailingTest()
    {
        var x = 4;
        var y = 2;
        var expectedResult = 8;

        var result = _basicMathService.Add(x, y);

        Assert.Equal(expectedResult, result);
    }
}

The code that we test against lives in a PCL and performs the calculations. Now let’s take these existing tests and execute them on the simulator or even a real device.

Running Tests on devices

For this first add the platforms on which the project will run. Now add the following xUnit.net NuGet package:

PM> Install-Package xunit.runner.devices -Version 1.0.0

Written by Oren Novotny whom we have to thank for enabling xUnit.net on Android, iOS and Windows Phone! This package will automatically add the xUnit.net and other dependencies required for running tests on your devices according to the platform to which it’s being added. Depending on the platform the xUnit.net for Devices package adds different template files as text files:

  • Android
    • MainActivity.cs.txt
  • iOS
    • AppDelegate.cs.txt
  • Windows Phone
    • MainPage.xaml.txt
    • MainPage.xaml.cs.txt

Simply replace the content of their default counterparts e.g. for iOS replace the AppDelegate.cs with the content of the App.Delegate.cs.txt (and thanks to some extra effort by Oren Novotny even the namespaces will just simply match Smile). Now you could simply start adding new class files and write out tests. The runner will automatically find them via reflection (even if you place them in subfolders).

Using existing tests

What is probably a more useful approach is to simply reuse existing tests. This is why in a next step lets see how we can add the unit test file BasicMathServiceTest.cs without creating a duplicate dopy. Simply right click on the Project then Add/Existing Item… browse to the unit test file and add it as link.

Shows the dropdown on the Add button that can be used to add a file as a link.

As a link to the file is simply a pointer to the original we only have to maintain one unit test file and all the links will automatically “update” as they simply reference the original.

Now the Project can be set as startup project and executed on the device. Bellow you see some sample screenshots from an iOS Emulator.

TestOverview

You can even dig into the error messages and see what went wrong during a test.

TestDetails

Conclusion

In this post we saw how to create and reuse xUnit.net tests on devices for iOS, Android and Windows. This can be very powerful when we have to test certain features on a device for example does this work with AOT on iOS? Or simply running integration tests on a real device, giving valuable insights and further allowing to tests performance, latency and so on.

This post focuses on xUnit.net and also shows one of it’s many strengths on the capabilities that can be easily added. The same can be done with NUnit which may be your testing framework of choice and which Xamarin provides project templates to run the tests on a device.

You can find the sample code on GitHub.