Month: February 2015

Authenticating AngularJS against OAuth 2.0 / OpenID Connect

I’ve recently found myself doing quite a bit of work putting in place an STS (Security Token Service) based around the excellent Thinktecture IdentityServer 3. I have a variety of different client types that need to authenticate including JavaScript Single Page Applications using the AngularJS framework.

IdentityServer 3 implements the Open ID Connect protocol for clients to authenticate against, Open ID Connect being an extension to OAuth 2.0.

There’s an existing open source plugin for authenticating with OAuth 2.0 called oauth-ng that utilises the implicit authentication flow that I wanted to use however I wanted some different behaviour and was interested in implementing my own plugin as a learning exercise with the protocol itself and with AngularJS. Massive credit to the author of that plug-in for inspiration and readable code, this is the first non-trivial AngularJS directive I’ve developed and so it was incredibly useful to be able to look at oauth-ng and riff off it’s design. As another reference the Adal-Angular project was also really useful.

The main features of the plugin I’ve developed are:

  • Sign in / sign out button
  • Specify which routes require a token for access to protected resources and automatically handle sign in if required when they are accessed
  • Storage of the token in the browsers session storage via the ngStorage module
  • Automatic insertion of a bearer token into HTTP requests once a user has authenticated

The plug-in can be found on GitHub here. It works and I’ve tested it against both Thinktecture IdentityServer3 and Google’s OAuth2 endpoint but is still quite early code in terms of testing and so if you encounter any issues please do log them on the GitHub issues page or submit a pull request with a fix.

All the code samples given below are from the sample app which is basically the Yeoman generated scaffold and that you can find on GitHub here and which I’ve configured to authenticate directly against Google. You will need to obtain your own client ID and configure Google as per the instructions here.

Getting Started

You can either grab the scripts from GitHub or, more easily, install the plugin as a bower package which you can install as follows:

bower install angularjs-oauth2 --save

First you’ll need to add the module to your applications list of dependencies in app.js and you need to make sure that ngStorage is also included:

angular
  .module('angularJsApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngStorage',
    'ngSanitize',
    'ngTouch',
    'afOAuth2'
  ])

The default template that is supplied for the sign in / out button expects to be placed inside a bootstrap navbar.

Typically in the above example you would select a scope appropriate to the resource you wished to access (if that terminology is confusing then I have a series of blog posts on the way as an intro to Open ID Connect and OAuth 2.0) – I’ve just picked one that we’ll have access to without additional configuration.

Now let’s modify the app.js file so that clicking the About link will require the user to be signed in:

.config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl',
        requireToken: true
      })
      .otherwise({
        redirectTo: '/'
      });
  });

Note the addition of requireToken:true to the route for about.

Now run the app (if you’re using the yeoman builder like myself then type grunt serve). You should see something much like the following appear in your browser:

indexScreen

The only difference from the standard Yeoman template (at least at the time I wrote this) is the Sign In button at the top right. If you click that, or the about link, then you should be redirected to the Google sign in page that looks like this:

signonSuccess

If you’ve not got things wired up “just so” in the Google console then you’ll see an error. Generally they are reasonably informative and normally, in my experience, the redirect URI in the console doesn’t quite match the redirect URI in the app (they’re sensitive over things like the / on the end or not).

After signing in the token will be added as an Authorization header to all http calls using the ‘Bearer my token’ format and so any calls you make to a remote resource that require authorisation will be supplied the token they need to verify the user.

Options

The oauth2 tag has a number of attributes that can be specified as follows.

authorisation-url: The URL to request the token from.
client-id: The client ID to supply to the token provider.
redirect-url: The URL the token provider should redirect to on a successful sign in.
response-type: Optional. The required token type. Defaults to token.
scope: The resources that access is requested to.
state: A magic number to send to the token provider to protect against CSRF attacks.
template: Optional. URL of a Angular template to use for the sign in / out button in place of the built in template.
buttonClass: Optional. Defaults to “btn btn-primary”. The class to apply to the button in the standard template.
signInText: Optional. Defaults to Sign In.
signOutText: Optional. Defaults to Sign Out.
signOutUrl: Optional. The URL to call to ask the token provider to perform a sign out. See notes on sign out below.
signOutAppendToken: Optional. Defaults to “false”. If set to “true” then the access token will be appended to the signOutUrl.
signOutRedirectUrl: Optional. The URL that the token provider, if it supports redirects, should redirect to following a sign out.

Signing Out

Signing out in the OAuth world can be… complicated. When the user presses the sign out button presented by this plug in the token that is stored in session storage is cleared and as we’re using session storage as soon as the session ends (window or tab closed) then they’ll be logged out.

However they may still be logged in with the token provider depending on how the token provider behaves and the options the user has selected their.

This plugin does allow a URL to be supplied to initiate a logout at the token provider where the token provider allows for that but if the token provider is using a persistent cookie and the user shuts the window without clicking sign out then they could remain logged in.

It’s worth thinking about if / when you choose to use OAuth.

Command Line Entity Framework Code First Migrations

As part of a continuous delivery pipeline today I wanted to automate the execution of Entity Framework Migrations from the command line. My first instinct was to see if I could add the EF PowerShell cmdlets to my PowerShell environment but it turns out these rely on the Visual Studio DTE context being available.

However it turns out that in the Entity Framework packages tools folder their is an executable that is supplied called migrate. It’s pretty simple to use but there are two caveats to running it:

  • It needs to be in the same folder as the assembly that contains the migrations
  • It needs to be in the same folder as the appropriate Entity Framework assembly

No big deal but on my main developer machine I still had an issue running it. Even though I copied it from the Entity Framework 6.1.2 folder, and only had that version of Entity Framework in use on my system, it complained about being run against the wrong version of Entity Framework – it appeared to be looking for version 5.0.0. This didn’t occur on a second machine but on the main developer machine I’ve had no end of problems getting Entity Framework to install the cmdlets correctly so I’m wandering if there is some cruft somewhere. In any case the fix was easy – I created a migrate.exe.config file to setup an assembly redirect as follows:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0-6.1.2" newVersion="6.1.2" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

With that in place migrate ran fine. In my instance I wanted to run it using a connection string supplied by the build script and so used a command as below:

1
migrate MyProject.Storage.Sql.dll /connectionString="Server=(local);Database=myprojectdb;Integrated Security=True;Connection Timeout=30;" /connectionProviderName="System.Data.SqlClient"

And that’s all there is to it. Migrate will figure out if it needs to create a new database or where in the migration chain the database sits and apply migrations accordingly.

This is one of those posts that is much a reminder for myself as anything else – nevertheless I hope it’s helpful.

Platform Specific Code and Portable Class Libraries

In my last post I looked at using view models, commands and behaviors in the user interface layer of applicatons to get a clean separation of concerns and make it easier to achieve a high level of code reuse and easy management when writing an application that targets multiple platforms by getting most of our code into portable class libraries leaving just a thin platform specific layer at the top aiming for an application architecture that looks roughly like this:

WinRT and Commanding (Architecture)

However at some point in such a project you are almost certainly going to find yourself needing to use platform specific features beyond just the user interface: perhaps the storage system, the networking system or a database. Below are my two most commonly used techniques for accessing platform specific features while maintaining a high level of code reuse and keeping a good separation of concerns. In a nutshell:

It’s important to realise that there is no such thing as a portable .net application. Portable class libraries always run within a non-portable .net target – be that Windows Store, iOS, Android or plain old Windows .Net. The two techniques presented below take advantage of this.

To go along with this blog post there is a Visual Studio solution in GitHub here containing worked examples that I’ll refer to below. The examples are stripped down to clearly illustrate specific points and so aren’t necessarily representative of production code. You can find them on GitHub here.

Dependency Injection

Perhaps the easiest way to access platform specific code from a portable class library is via dependency injection. To utilise this technique all you do is declare interfaces within your portable class libraries and provide implementations within your non-portable application targets.

To illustrate how this works I’m going to create a simple application that writes a hello world text file to the local folder of an app. The final output of the below worked example can be found in the DependencyInjection project in GitHub here.

Firstly create a new solution and into it add two projects – a Windows Store app and a Portable Class library. In my example solution they are called DependencyInjection.WindowsStore and DependencyInjection.Domain. Set the Windows Store project to reference the domain project.

In the domain project I declare an interface IFileWriter:

1
2
3
4
public interface IFileWriter
{
    Task Write(string filename, byte[] bytes);
}

And a simple domain class that outputs my message using the supplied file writer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class BasicDomainImplementation
{
    private readonly IFileWriter _fileWriter;
 
    public BasicDomainImplementation(IFileWriter fileWriter)
    {
        _fileWriter = fileWriter;
    }
 
    public async Task WriteBytes()
    {
        await _fileWriter.Write("somebytes.txt", Encoding.UTF8.GetBytes("Hello World"));
    }
}

In the Windows Store target add an implementation of the IFileWriter class that, you’ll note, uses decidedly non-portable API calls:

1
2
3
4
5
6
7
8
internal class FileWriterImpl : IFileWriter
{
    public async Task Write(string filename, byte[] bytes)
    {
        StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename);
        await FileIO.WriteBytesAsync(file, bytes);
    }
}

Then add a button to the MainPage.xaml file:

1
<Button HorizontalAlignment="Center" Content="Write Some Bytes" Click="WriteSomeBytes"></Button>

And add the event handler in the code behind:

1
2
3
4
5
6
private async void WriteSomeBytes(object sender, RoutedEventArgs e)
{
    IFileWriter fileWriter = new FileWriterImpl();
    BasicDomainImplementation domainImplementation = new BasicDomainImplementation(fileWriter);
    await domainImplementation.WriteBytes();
}

If you run the project and click the button the file will be created and the bytes written. If you click the button a second time you’ll get a “file exists” exception.

So what have I done here? It’s pretty simple really: I’ve defined an interface in a portable class library for which I have supplied the implementation from a platform targetted library letting me keep the PCL blissfully unaware of the mechanics of writing bytes to a file in a Windows Store app.

It’s a very simple example but you can see how this approach can be extended to abstract away all sorts of platform specific complexity from your domain assemblies. Over time you’re likely to build up a useful set of abstractions for platform features that you’re using in your apps which leads us nicely to the next approach.

Bait and Switch PCLs

There is a “trick” you can do with portable class libraries called bait and switch that relies on the fact that NuGet will always prefer a platform specific assembly to a portable class library. You can use this to build NuGet packages that allow platform specific code to, seemingly, be mixed with portable code.

Additionally some dependencies are supplied only in platform specific binary forms – the most common example in the App world probably being SQLite, used widely across iOS and Android for structured local device storage and while perhaps newer to Windows developers it’s just as useful for the same reasons in Store apps.

However it’s supplied as a platform specific binary which begs the question – how do you use this in a portable class library?

To illustrate how this works I’m going to use Frank Krueger’s excellent SQLite client for .Net with a Windows Store app. The final output of the below worked example can be found in the BaitAndSwitch project in Github here.

Firstly create a new solution and into it add two projects – a Windows Store app and a Portable Class library. Using NuGet add Unity In my example solution they are called BaitAndSwitch.WindowsStore and BaitAndSwitch.Domain.

Add the sqlite-net-pcl package to the portable class library either using the NuGet package manager GUI or the console:

Install-Package sqlite-net-pcl

If you look at the references added to the project you’ll see that the project now contains references to SQLite-net (Frank Kreuger’s SQLite client) and something called SQLitePCL.raw. This latter assembly is the “bait and switch” assembly developed by Eric Sink and for which the source is in GitHub here. I’ll come back to it shortly.

I don’t want to get bogged down in SQLite while illustrating the bait and switch technique so all I’ll do is create a basic storage model and create a database file using it for the schema.

In my sample project I created a poco as follows:

1
2
3
4
5
6
7
8
9
public class Person
{
    [PrimaryKey]
    public int Id { get; set; }
 
    public string Name { get; set; }
 
    public int Age { get; set; }
}

And a class with a single method for creating our database:

1
2
3
4
5
6
7
8
9
10
11
public class Storage
{
    public void Initialize(string path)
    {
        string databaseFilename = Path.Combine(path, "mydatabase.sql");
        using (SQLiteConnection connection = new SQLiteConnection(databaseFilename))
        {
            connection.CreateTable<Person>();
        }
    }
}

In MainPage.xaml of the Windows Store app next add a button to the main grid:

1
<Button Content="Initialize Storage" HorizontalAlignment="Center" Click="InitializeStorage"></Button>

And in the code behind event handler (of course having read my last post you’d never do this right!):

1
2
3
4
5
private void InitializeStorage(object sender, RoutedEventArgs e)
{
    Storage storage = new Storage();
    storage.Initialize(ApplicationData.Current.LocalFolder.Path);
}

If you run the app at this point and click the button you’ll get an exception with an interesting message:

Something went wrong in the build configuration. This is the bait assembly, which is for referencing by portable libraries, and should never end up part of the app. Reference the appropriate platform assembly instead.

So what’s going on here and how do we fix it? This exception is raised by the SQLitePCL.raw assembly and to understand what’s going on we need to lift the lid on the NuGet package a little. This is the contents of the packages lib folder:

sqlitepclrawlib

You can see there are provided assemblies for a whole host of targets including portable class libraries and “real” executable targets. If you were to decompile one of portable assemblies using a tool such as dotPeek and look at the SQLite3Provider class you’d see methods like:

1
2
3
4
int ISQLite3Provider.sqlite3_open(string filename, out IntPtr db)
{
    throw new Exception("Something went wrong in the build configuration.  This is the bait assembly, which is for referencing by portable libraries, and should never end up part of the app.  Reference the appropriate platform assembly instead.");
}

The portable versions of the assemblies are never meant to actually be run. Whereas if you look at the same method in the net45 targetted assembly you’ll see the below:

1
2
3
4
int ISQLite3Provider.sqlite3_open(string filename, out IntPtr db)
{
	return SQLite3Provider.NativeMethods.sqlite3_open(util.to_utf8(filename), out db);
}

So how do we get our application to use the correct version of the assembly for our target? Well we could fiddle around with file copying and complicated build set ups but remember what I said about NuGet earlier: it will always prefer a platform specific assembly to a portable class library. To take advantage of this all we need to do is also add the SQLitePCL.raw NuGet package to our Windows Store project:

Install-Package SQLitePCL.raw_basic

Now before building and running the application pick a target – you can’t run sqlite3 under Any CPU. Change to x86 or x64 and hit run (if you don’t do this then you’ll get further than before – the correct SQLitePCL.raw assembly will be used but it won’t be able to find the sqlite3.dll C library). If you tap the Initialize button now the database will be created – the version of the assembly making it’s way into our final target is the one most appropriate for it, which is no longer the “bait” PCL version but the Windows Store version.

It’s worth noting that you can use this approach to share code yourself and this is my favoured approach for sharing my own library code across my projects. Once you understand how to use them and roughly how they work it’s fairly simple to do and I’ll cover building a Bait and Switch PCL NuGet package in an upcoming post.

WinRT, Commanding and Cross Platform Apps – Part 1

Disclaimer: this isn’t really a blog post about Azure but it is quite topical with Windows 10 around the corner and with so many mobile apps making use of Azure in some fashion. I’ve also got a pretty substantial new application almost ready for release into the wild and so in some ways this blog post is a prelude to that – the source code for that app will be available under the MIT License.

With that out the way – I’ve been doing a lot of work with Windows Store apps recently using the WinRT runtime, both converting existing iOS apps to Windows and writing new cross platform apps from the ground up. That’s involved a fair bit of Xaml and although it’s not my first brush with Microsoft’s Xaml family of user interface technologies, indeed one of my favourite roles was working, a few years ago now, as the architect on the Capita SIMS Discover product with a fantastic team. However the last few months is the first time I’ve really had to immerse myself in the Xaml itself – on Discover my hands on work was mostly in the built from scratch data analysis engine and service hosting (and I spent an awful lot of time pretending to be wise!).

Something that always seems to be glossed over by Microsoft in their documentation and developer guides is how to achieve a clean separation between your view models and your Xaml. Although Microsoft often talk about MVC and MVVM most of the patterns in their own examples and tutorials rely on lots of code behind wired up with event handlers. And it’s not clear initially, at least it never was to me, what technology I should use to move away from this mess though fortunately I had one of the UKs best WPF developers – Adam Smith – on hand to point me in the right direction. That being the case when I started working with WinRT I had a reasonable idea of where to head.

A clean separation between the user interface and a domain layer promotes a more testable code base and also allows for a separation of developer and design disciplines (if needed) but if you’re a cross platform app developer using Xamarin to target iOS and Android in addition to Windows then, perhaps even more importantly, getting this separation right is absolutely essential if you want to achieve a high level of code reuse. Which presumably is why you’re using Xamarin in the first place – you’ve been sold on the dream!

In the Xaml WinRT space the key to achieving this are commands and behaviors – and these concepts translate nicely onto the other platforms. I’m going to look at command basics in this post and then follow up with some more advanced concepts and finally I’ll discuss some strategies for dealing with platform specific code.

For the remainder of this post I’m going to assume you have a working knowledge of Xaml, C# and the binding system. The Windows Store Developer site is a good place to start if you’re not. To go along with this post I’ve added a solution to GitHub that contains working examples of everything I’ll discuss. You can find it here.

If you’re reading this then like myself at the same stage in this journey you’ve noticed the word “command” used around the Windows Store developer website, at the time of writing the MSDN developer guide to commanding has this to say on the subject:

A small number of UI elements provide built-in support for commanding. Commanding uses input-related routed events in its underlying implementation. It enables processing of related UI input, such as a certain pointer action or a specific accelerator key, by invoking a single command handler.

If commanding is available for a UI element, consider using its commanding APIs instead of any discrete input events. For more info, see ButtonBase.Command.

You can also implement ICommand to encapsulate command functionality that you invoke from ordinary event handlers. This enables you to use commanding even when there is no Command property available.

Well it’s a start I guess but then the rest of the document proceeds to gloss over this sage wisdom, pushing it to one side like a mouldy sock. I guess it doesn’t look quite so good in a drag and drop coding demo. That’s the final bit of snark – I promise. And it is, to be fair, snark born of well intentioned frustration – Microsoft have a pretty decent UI framework in Xaml but it’s best practice usage is buried away while poor practice usage is pushed massively to the fore and this is a great frustration for me.

Anyway, back on track, what does this boil down to in code? How do we attach a command to a button and have it do something. There is an example of this in the GitHub repository in the BasicCommanding project. This puts a text box and a button on the screen and when you press the button the message changes without an OnClick event handler in sight. First off I start with a view model that looks like this:

1
2
3
4
5
6
7
8
9
10
11
public class BasicViewModel : BindableBase
{
    public ICommand UpdateMessageCommand { get; set; }
 
    private string _message;
    public string Message
    {
        get {  return _message;}
        set { SetProperty(ref _message, value); }
    }
}

You can see that we have a property for our update command of type ICommand (the key interface for commands) and a simple message. This derives from a class called BindableBase that deals with the binding notifications for us.

Then our command looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class UpdateMessageCommand : ICommand
{
    private readonly BasicViewModel _model;
 
    public UpdateMessageCommand(BasicViewModel model)
    {
        _model = model;
    }
 
    public bool CanExecute(object parameter)
    {
        return true;
    }
 
    public void Execute(object parameter)
    {
        _model.Message = "Goodbye!";
    }
 
    public event EventHandler CanExecuteChanged;
}

This implements the ICommand methods and properties (CanExecute, Execute and CanExecuteChanged) but importantly the constructor takes a reference to an instance of our model and the Execute method updates the message.

Finally we have a few lines of Xaml for bringing this together:

<TextBlock VerticalAlignment="Center" Grid.Column="0" Grid.Row="1" Text="Message"></TextBlock>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Message}" IsReadOnly="True"></TextBox>
<Button Grid.Column="2" Grid.Row="1" Content="Update message" Command="{Binding UpdateMessageCommand}"></Button>

You can see that the text of the textbox is bound to our view models message property and the Command property on the button to our command. If you run the sample and click the button you’ll find that, yes, our command is invoked and the message updated and other than associating the view model with the pages data context we have no “code behind” at all.

Furthermore by combining the command with the binding system we don’t get involved in manipulating the user interface directly in our applications domain layer – there is no MyTextBox.Text = “New Value” type code going on and as each such piece of code is a nail in the coffin of cross platform portability that’s rather neat.

That’s the second time I’ve mentioned a domain layer. In the context of a cross platform application by this I mean a layer that implements all your applications state and business logic via view models, commands, and (where appropriate) interactions with service and storage layers. For a typical cross platform app, and in fact the app I’m working on now looks just like this, you end up with something like this:

WinRT and Commanding (Architecture)

Essentially you’re aiming for the thinnest possible layer of platform specific code targetting each platform, below that a domain layer as a portable class library, and it co-ordinating activity between other components of your system such as data access or remote service calls – again with the latter being portable class libraries. Dependencies sometimes means it’s not possible or practical to use portable class libraries end to end without significant work, for example perhaps a significant NuGet package you rely on is only available in native WinRT, iOS and Android form, but in that case you still want to maintain the same kind of structure with different targets but the code staying the same. I’ll cover some of these strategies some other time – the important thing to realise is that commands, view models, and behaviors are key enables of this strategy as they are what allow you to pull your platform specific UI layer away from the rest of your code.

All sounds great so far but the problem you’ll quickly run into is that not all of the controls available to you have a command property and on those that do, such as the Button, how do you handle other events. You can do this by adding the Behaviors SDK in your project. One way to do this is to use the Blend visual design tool but I want to focus on code in this post so staying in Visual Studio add a reference to your project and in the Reference Manager select Windows 8.1 Extensions and then tick Behaviors SDK (XAML) as in the screenshot below:

ReferenceManager

Amongst other thngs this adds a set of what are known as Behaviors to your project and perhaps the most immediately useful of these is the EventTriggerBehavior. You can attach one or more of these to any control and they will allow you to capture events and handle them through bound commands as in our previous example.

To demonstrate this I have a second example (EventCommanding in the GitHub repository) that changes the text of a TextBlock as you move the pointer over it and out. Without commanding you’d add code to the PointerEntered and PointerExited events. With commands…. well let’s take a look. Here’s the view model for this example, as you can see it’s very similar to the previous view model except there are two commands this time.

1
2
3
4
5
6
7
8
9
10
11
12
public class BasicViewModel : BindableBase
{
    public ICommand StartCommand { get; set; }
    public ICommand EndCommand { get; set; }
 
    private string _message;
    public string Message
    {
        get { return _message; }
        set { SetProperty(ref _message, value); }
    }
}

Our commands look just like our previous command, below is the StartCommand:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class StartCommand : ICommand
{
    private readonly BasicViewModel _model;
 
    public StartCommand(BasicViewModel model)
    {
        _model = model;
    }
 
    public bool CanExecute(object parameter)
    {
        return true;
    }
 
    public void Execute(object parameter)
    {
        _model.Message = "Move pointer out";
    }
 
    public event EventHandler CanExecuteChanged;
}

Finally the Xaml below shows how you use the EventTriggerBehavior from the Behaviors SDK to use these commands instead of event handlers in code behind:

1
2
3
4
5
6
7
8
9
10
<TextBlock ManipulationMode="All" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Red" Text="{Binding Message}" FontSize="18">
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="PointerEntered">
            <Core:InvokeCommandAction Command="{Binding StartCommand}"/>
        </Core:EventTriggerBehavior>
        <Core:EventTriggerBehavior EventName="PointerExited">
            <Core:InvokeCommandAction Command="{Binding EndCommand}"/>
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</TextBlock>

Again in this example we’ve been able to use commands and binding to update our user interface based on user input without any need to reference UI controls directly. It’s easy to see how this approach leads to a clean separation of concerns, better testability, and how we might use these techniques to help us build high code reuse cross platform apps.

In part 2 of this post I’ll cover some more advanced topics about commands and behaviors, for example capturing additional information from events such as in our earlier example the position of the pointer, look at some of the other behaviors in the SDK and take a look at how we can combine them with value converters to further improve our cross platform friendliness.

Contact

  • If you're looking for help with C#, .NET, Azure, Architecture, or would simply value an independent opinion then please get in touch here or over on Twitter.

Recent Posts

Recent Tweets

Invalid or expired token.

Recent Comments

Archives

Categories

Meta

GiottoPress by Enrique Chavez