Monthly Archives: April 2019

Adding OneDrive support to an application

I wanted to create an application which stores data for synchronisation between devices, so figured the cheapest way might be to use one of the free storage mediums, in this case OneDrive.

  • Create an application, mine’s a WPF app.
  • Add the NuGet package Microsoft.OneDriveSDK
  • Add the NuGet package Microsoft.OneDriveSdk.Authentication

Note: Windows allows the storage of data to the user’s roaming profile to be stored in the “cloud”. So if your application is solely Windows based this might be a better solution than using OneDrive directly.

Registering our application

Before we get into any coding we’ll need to register our application with the Microsoft Application Registration Portal, instructions can be found here.

Basically you’ll be prompted to log into the Microsoft Application Registration Portal, then you should Add your application, supplying it with a name. Once completed, this will supply us with an application id and application secrets.

As my sample application is a native application then I don’t need to create an app password.

Just click Add Platform and add the platforms you are wanting to support (again mine’s a simple native application).

Writing some code

First off we’ll need to authenticate the user, so we use an authentication adapter. Here’s my code

var msaAuthenticationProvider = new MsaAuthenticationProvider(
   AppId,
   "https://login.live.com/oauth20_desktop.srf",
   new[] { "onedrive.readwrite", "offline_access" });

When you run this code, you’ll be presented with a login screen requiring username/email and password, then a dialog to tell you your application is requesting permissions to access OnDrive and asking you to grant or deny them.

Authorisation scopes, such as onedrive.readonly can be found here.

Now we need to authenticate and access the one drive client.

await msaAuthenticationProvider.AuthenticateUserAsync();

var oneDriveClient = new OneDriveClient(
   "https://api.onedrive.com/v1.0", 
   msaAuthenticationProvider);

Once we get an instance of the OneDriveClient we can interact with the One Drive files/file system. Here’s an example snippet of code which gets to a know folder location, for example imagine we have a folder named Public/MyApp then we could use

var item = await 
   oneDriveClient
      .Drive
      .Root
      .ItemWithPath("Public/MyApp")
      .Request()
      .GetAsync();

We can also use a “special folder” which the application data is stored to by changing the permission scope to onedrive.appfolder, for example

var msaAuthenticationProvider = new MsaAuthenticationProvider(
   AppId,
   "https://login.live.com/oauth20_desktop.srf",
   new[] { "onedrive.appfolder", "offline_access");


await msaAuthenticationProvider.AuthenticateUserAsync();

var item = await oneDriveClient
   .Drive
   .Special
   .AppRoot
   .Request()
   .GetAsync();

Further Reading

OneDrive Dev Center
Official projects and SDKs for Microsoft OneDrive
Using an App Folder to store user content without access to all files

Using Microsoft.Extensions.Logging

The Microsoft.Extensions.Logging namespace includes interfaces and implementations for a common logging interface. It’s a little like common-logging and whilst it’s not restricted to ASP.NET Core it’s got things entry points to work with ASP.NET Core.

What’s common logging all about?

In the past we’ve been hit with the problem of multiple logging frameworks/libraries which have slightly different interfaces. On top of this we might have other libraries which require those specific interfaces.

So for example, popular .NET logging frameworks such as log4net, NLog, Serilog along with the likes of the Microsoft Enterprise Block Logging might be getting used/expected in different parts of our application and libraries. Each ultimately offers similar functionality but we really don’t want multiple logging frameworks if we can help it.

The common-logging was introduced a fair few years back to allow us to write code with a standarised interface, but allow us to use whatever logging framework we wanted behind the scenes. Microsoft’s Microsoft.Extensions.Logging offers a similar abstraction.

Out of the box, the Microsoft.Extensions.Logging comes with some standard logging capabilities, Microsoft.Extensions.Logging.Console, Microsoft.Extensions.Logging.Debug, Microsoft.Extensions.Logging.EventLog, Microsoft.Extensions.Logging.TraceSource and Microsoft.Extensions.Logging.AzureAppServices. As the names suggest, these give us logging to the console, to debug, to the event log, to trace source and to Azure’s diagnostic logging.

Microsoft.Extensions.Logging offers is a relatively simple mechanism for adding further logging “providers” and third part logging frameworks such as NLog, log4net and SeriLog.

How to use Microsoft.Extensions.Logging

Let’s start by simply seeing how we can create a logger using this framework.

Add the Microsoft.Extensions.Logging and Microsoft.Extensions.Logging.Debug NuGet packages to your application.

The first gives us the interfaces and code for the LoggerFactory etc. whilst the second gives us the debug extensions for the logging factory.

Note: The following code has been deprecated and replaced with ILoggerBuilder extensions.

var factory = new LoggerFactory()
   .AddDebug(LogLevel.Debug);

Once the logger factory has been created we can create an ILogger using

ILogger logger = factory.CreateLogger<MyService>();

The MyService may be a type that you want to create logs for, alternatively you can pass the CreateLogger a category name.

Finally, using a standard interface we can log something using the following code

logger.Log(LogLevel.Debug, "Some message to log");

Using other logging frameworks

I’ll just look at a couple of other frameworks, NLog and Serilog.

For NLog add the NuGet package NLog.Extensions.Logging, for Serilog add Serilog.Extensions.Logging and in my case I’ve added Serilog.Sinks.RollingFile to create logs to a rolling file and Serilog.Sinks.Debug for debug output.

Using NLog

Create a file named nlog.config and set it’s properties within Visual Studio as Copy always. Here’s a sample

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
   xsi:schemaLocation="NLog NLog.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   autoReload="true"
   internalLogFile="c:\temp\mylog.log"
   internalLogLevel="Info" >


<targets>
   <target xsi:type="File" name="fileTarget" 
      fileName="c:\temp\mylog.log"      
      layout="${date}|${level:uppercase=true}|${message}
         ${exception}|${logger}|${all-event-properties}" />
   <target xsi:type="Console" name="consoleTarget"
      layout="${date}|${level:uppercase=true}|${message} 
         ${exception}|${logger}|${all-event-properties}" />
</targets>

<rules>
   <logger name="*" minlevel="Trace" writeTo="fileTarget,consoleTarget" />
</rules>
</nlog>

Now in code we can load this configuration file using

NLog.LogManager.LoadConfiguration("nlog.config");

and now the only difference from the previous example of using the LoggerFactory is change the creation of the factory to

var factory = new LoggerFactory()
   .AddNLog();

Everything else remains the same. Now you should be seeing a file named mylog.log in c:\temp along with debug output.

Using serilog

In Serilog’s case we’ll create the logger configuration in code, hence here’s the code to create both a file and debug log

Note: See Serilog documentation for creating the configuration via a config or settings file.

Log.Logger = new LoggerConfiguration()
   .MinimumLevel.Debug()
   .WriteTo.RollingFile("c:\\temp\\log-{Date}.txt")
   .WriteTo.Debug()
   .CreateLogger();

The will create a log file in c:\temp named log-{Date}.txt, where {Date} is replaced with today’s date. Obviously the include of WriteTo.Debug also gives us debug output.

We simply create the logger using familiar looking code

var factory = new LoggerFactory()
   .AddSerilog();

Everything else works the same but now we’ll see Serilog output.

Creating our own LoggerProvider

As you’ve seen in all examples, extension methods are used to AddDebug, AddNLog, AddSerilog. Basically each of these adds an ILoggerProvider to the factory. We can easily add our own provider by implementing the ILoggerProvider interface, here’s a simple example of a DebugLoggerProvider

public class DebugLoggerProvider : ILoggerProvider
{
   private readonly ConcurrentDictionary<string, ILogger> _loggers;

   public DebugLoggerProvider()
   {
      _loggers = new ConcurrentDictionary<string, ILogger>();
   }

   public void Dispose()
   {
   }

   public ILogger CreateLogger(string categoryName)
   {
      return _loggers.GetOrAdd(categoryName, new DebugLogger());
   }
}

The provider needs to keep track of any ILogger’s created based upon the category name. Next we’ll create a DebugLogger which implements the ILogger interface

public class DebugLogger : ILogger
{
   public void Log<TState>(
      LogLevel logLevel, EventId eventId, 
      TState state, Exception exception, 
      Func<TState, Exception, string> formatter)
   {
      if (formatter != null)
      {
         Debug.WriteLine(formatter(state, exception));
      }
   }

   public bool IsEnabled(LogLevel logLevel)
   {
      return true;
   }

   public IDisposable BeginScope<TState>(TState state)
   {
      return null;
   }
}

In this sample logger, we’re going to handle all LogLevel’s and are not supporting BeginScope. So all the work is done in the Log method and even that is pretty simple as we use the supplied formatter to create our message then output it to our log sink, in this case Debug. If no formatter is passed, we’ll currently not output anything, but obviously we could create our own formatter to be used instead.

Finally, sticking with the extension method pattern to add a provider, we’ll create the following

public static class DebugLoggerFactoryExtensions
{
   public static ILoggerFactory AddDebugLogger(
      this ILoggerFactory factory)
   {
      factory.AddProvider(new DebugLoggerProvider());
      return factory;
   }
}

That’s all there is to this very simple example, we create the factory in the standard way, i.e.

var factory = new LoggerFactory()
   .AddDebugLogger();

and everything else works without any changes.

Running tibrvlisten

I keep forgetting this command, so time to blog about it

Occasionally, we’ll want to monitor RV messages being received on our host machine, to do this we can use the tibrvlisten.exe application from the command prompt along with the appropriate arguments. tibrvlisten.exe will filter and display the RV messages as they arrive on the host computer.

An example of use might be

tibrvlisten -service 1234 -network ;123.123.123.123 "mytopics.>"

The -service is the port being used for RV, followed by the IP address of the network it’s on. Note the ; preceding the IP address. Also in this case, I’m filtering what tibrvlisten outputs to the screen by displaying only those messages which start with mytopics. and using the wildcard > symbol.

A few dir/ls/Get-ChildItem Powershell commands

Get-ChildItem is aliased as ls/dir (as well as gci), so is used to list files and directories.

Here’s a few useful commands

Find only folders/directories

ls -Directory

Find only files

ls -File

Find files with a given extension

ls -Recurse | where {$_.Name -like "*.bak"}

Only search to a certain depth

The above will recurse over all folders, but we might want to restrict this by a certain depth level, i.e. in this example up to 2 directories deep

ls -Recurse -Depth 2 | where {$_.Name -like "*.bak"}

Finding the directories with files with a given extension

ls -Recurse -Depth 2 | where {$_.Name -like "*.bak"} | select directory -Unique

The use of -Unique ensure we do not have multiple directories with the same path/name (i.e. for each .bak file found within a single directory)

Speech synthesis in Windows with C#

As part of a little side project, I wanted to have Windows speak some text is response to a call to a service. Initially I started to look at Cortana, but this seemed overkill for my initial needs (i.e. you need to write a bot, deploy it to Azure etc.), whereas System.Speech.Synthesis offers a simple API to use text to speech.

Getting started

It can be as simple as this, add the System.Speech assembly to your references then we can use the following

using (var speech = new SpeechSynthesizer())
{
   speech.Volume = 100; 
   speech.Rate = -2; 
   speech.Speak("Hello World");
}

Volume takes a value between [0, 100] and Rate which is the speaking rate can range between [-10, 10].

Taking things a little further

We can also look at controlling other aspects of speech such as emphasis, when the word should be spelled out and ways to create “styles” for different sections of speech. To use these we can use the PromptBuilder. Let’s start by create a “style” for a section of speech

var promptBuilder = new PromptBuilder();

var promptStyle = new PromptStyle
{
   Volume = PromptVolume.Soft,
   Rate = PromptRate.Slow
};

promptBuilder.StartStyle(promptStyle);
promptBuilder.AppendText("Hello World");
promptBuilder.EndStyle();

using (var speech = new SpeechSynthesizer())
{
   speech.Speak(promptBuilder);
}

We can build up our speech from different styles and include emphasis using

promptBuilder.AppendText("Hello ", PromptEmphasis.Strong);

we can also spell out words using

promptBuilder.AppendTextWithHint("Hello", SayAs.SpellOut);

Speech Recognition

The System.Speech assembly also includes the ability to recongize speech. This will require the Speech Recongition software within Windows to run (see Control Panel | Ease of Access | Speech Recognition.

To enable your application to use speech recognition you need to execute the following

SpeechRecognizer recognizer = new SpeechRecognizer();

Just executing this will allow the speech recognition code (on the focused application) to do things like execute button code as if the button was pressed. You can also hook into events to use recogonised speech within your application, for example using

SpeechRecognizer recognizer = new SpeechRecognizer();
recognizer.SpeechRecognized += (sender, args) => 
{ 
   input.Text = args.Result.Text; 
};

gitconfig, the where and how’s

The git configuration files are stored at three different levels.

Local are stored within the cloned repository’s .git folder and the file is named config.

Global is stored in a file with no name and with the extension .gitconfig. It’s stored in your home directory. On Windows this can be confusing especially if the home directory is in a roaming profile. For example, normally we’d find the it in c:\users\your-user-name, however if you have a roaming profile then you’ll need to check

HOME="$HOMEDRIVE$HOMEPATH"

So for example this might end up as H:\

System is stored as gitconfig (filename but no extension). In the case of a Windows OS, this will be in C:\Program Files\Git\mingw64\etc, further configuration data may be found in the config file (filename but no extension) within C:\ProgramData\Git.

Scope

The scope of these files is as follows, local overrides global options and global overrides system.

List the configurations

If you execute the command below, you’ll see a list of all the configuration along with the location of the files used.

git config --list --show-origin

Note: beware if passwords are stored in the configuration then these will be displayed when you run this command.

The command does not show you what’s “actually” being used for configuration from the current repo. so much as “here’s all the configuration values”, so you’ll need to look at the scope of each file to determine what values are currently being used by git.

We can also use the same command along with the switch –local, –system and –global to list the files used along with the configuration used.

Further reading

git-config
git config (Atlassian)

A .NET service registered with Eureka

To create a .NET service which is registered with Eureka we’ll use the Steeltoe libraries…

Create an ASP.NET Core Web Application and select WebApi. Add the Steeltoe.Discovery.Client NuGet package, now in the Startup.cs within ConfigureServices add the following

services.AddDiscoveryClient(Configuration);

and within the Configure method add

app.UseDiscoveryClient();

We’re not going to create any other code to implement a service, but we will need some configuration added to the appsettings.json file, so add the following

"spring": {
    "application": {
      "name": "eureka-test-service"
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldRegisterWithEureka": true,
      "shouldFetchRegistry": false
    },
    "instance": {
      "hostname": "localhost",
      "port": 5000
    }
  }

The application name is what’s going to be displayed within Eureka and visible via http://localhost:8761/eureka/apps (obviously replacing the host name and ip with your Eureka server’s).

Spring boot Eureka server

Using Spring boot, we can very easily run up a Eureka server.

In IntelliJ create a new project using the Spring Initializr, simply select the Eureka Server dependency.

Once the application is create, I found I needed to add the @EnableEurekaServer annotation to the application class, so here’s my EurekatesApplication.java

package com.putridparrot.eurekatest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekatestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekatestApplication.class, args);
    }
}

Next we need to add the following properties to the resources/application.properties

server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF

Now when you run the application and view the web page http://localhost:8761/, you should see the Spring Eureka web page. Running http://localhost:8761/eureka/apps from your preferred browser will list any applications registered with the server.

At this point we’ve not application registered with the server, so let’s add a .NET server in the next post.

Xamarin UITest (on Android)

Having used the likes of TestStack.White in the past I was interested in trying out the Xamarin UITest library for executing tests against my mobile application’s UI.

For now I’m primarily discussing testing against an Android device or emulator, but I will amend the post as and when I run tests against iOS.

Some problems and solutions

It didn’t go smoothly, initially, getting a project running. Hence, this part of the post is going to cover some of the issues I had and some of the possible solutions.

  • If you have platform-tools.old followed by a number of digits within C:\Program Files (x86)\Android\android-sdk (for example platform-tools.old1970091580), either delete these folders or for safety’s sake, move them outside of the C:\Program Files (x86)\Android\android-sdk folder, otherwise running the UITests seems to get confused which adk it should use.
  • Add an environment variable (if not already existing) named ANDROID_HOME and set it’s value to your install of the android-sdk, i.e. C:\Program Files (x86)\Android\android-sdk
  • The version of the UITest NuGet package seems to be related to the version of the Android SDK, so after you’ve created a UITest project and added the Xamarin.UITest package, depending on the Android SDK you might need to get a previous version of this package – in my case I’m using Xamarin.UITest version 2.2.7.0 and Android SDK Tools 26.1.1
  • For an Android application, we need to set the project properties Android Manifest, Required permissions to include the INTERNET permission
  • For Android projects we need to run against a Release build
  • Again for Android projects, if we added a UITest project which include the ApplInitializer.cs file, we need to supply the application name or the path to the .apk file being used, for example
    if(platform == Platform.Android)
    {
       return ConfigureApp
          .Android
          .InstalledApp("com.putridparrot.MyApp")
          .PreferIdeSettings()
          .EnableLocalScreenshots()
          .StartApp();
    }
    

    Note: In place of InstalledApp we could use ApkFile with the path of our apk file, i.e.

       .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
    
  • If you’ve previously installed your application on the emulator or device, I found it best to manually uninstall it first
  • Before running your tests, make sure the emulator is running or the device is connected (I know, probably obvious)

Creating our UI test project

  • Add a Xamarin.UITest Cross-Platform Test Project to your solution
  • Build the project so it restores any missing NuGet packages, I needed to update the following packages to Xamarin.UITest version 2.2.7.0 and NUnit 3.11.0.0
  • Deploy your application to your device before running the tests
  • When running your tests, they may take a little time before you see anything happening on the emulator or device – so don’t be too impatient.

Before we can actually run our tests (which we’ll discuss next) we need to build our application and generate an APK for Android (if running against Android).

Writing our UI tests

To allow our UITests to locate controls in our user interface we supply each control (that we need to interact with) with an AutomationId, this should be unique (so it’s easy for our tests to locate).

For Android application I found this configuration works (obviously replace the ApkFile location/name with your apk).

if(platform == Platform.Android)
{
   return ConfigureApp
      .Android
      .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
      .PreferIdeSettings()
      .EnableLocalScreenshots()
      .StartApp();
}

Note: we should be able to replace the ApkFile line with .InstalledApp(“com.putridparrot.MyApp”) if you prefer.

The UITest project will require an AppInitializer.cs file which, if you created via the project template, will be included. Here’s an example of one

public class AppInitializer
{
   public static IApp StartApp(Platform platform)
   {
      if(platform == Platform.Android)
      {
         return ConfigureApp
            .Android
            .InstalledApp("com.putridparrot.MyApp")
            .PreferIdeSettings()
            .EnableLocalScreenshots()
            .StartApp();
     }
     return ConfigureApp
        .iOS
        .StartApp();
}

Test files (again the project template will include a Tests.cs file) might look like this

[TestFixture(Platform.Android)]
[TestFixture(Platform.iOS)]
public class Tests
{
   private IApp _app;
   private readonly Platform _platform;

   private static readonly 
      Func<AppQuery, AppQuery> LoginButton = 
         c => c.Marked("Login");

   public Tests(Platform platform)
   {
      _platform = platform;
   }

   [SetUp]
   public void BeforeEachTest()
   {
      _app = AppInitializer.StartApp(_platform);
   }

   [Test]
   public void DoesNothing()
   {
      // Arrange
      // Act
      // Assert
   }
}

Writing UI tests is much the same as writing standard unit tests, we mark our test methods with the NUnit TestAttribute, then Arrange, Act and Assert our UI. For example let’s assume we have a button with an AutomationId Login then we can create a static field within our Test class like this

private static readonly 
   Func<AppQuery, AppQuery> LoginButton = 
      c => c.Marked("Login");

This function can be used within various _app methods, such as _app.Tap(LoginButton).

As you’ve guessed I’m testing a login UI, so assuming we have a login screen with username, password and a login button we might setup our tests like this…

First Arrange our UI, for example check that we’re on the correct screen and we’ve entered a username and password. Then we’d Act by tapping the Login button then finally Assert by checking we’ve moved on from the Login screen.

REPL

When we run our tests we might want to run the _app.Repl() method which will display a REPL command line, this allows us to view the tree representing our UI.

References

Cannot run XAMARIN UI TEST on xamarin.forms, error System.Exception

The Elvis (conditional null) operator is not magic

I was looking over somebody else’s code the other day and was intrigued by the liberal use of the Elvis or correctly known as, conditional null operator, i.e. the ?.

I assumed that for every ?. the compiler would create an IF statement, but it did make me wonder whether the compiler was actually able to optimize such code (where the ?. is used multiple times on the same object), so for example, what’s produced in IL for the following

var s = ??? // null or an instance 
Console.WriteLine(s?.Name?.Length);
Console.WriteLine(s?.Name);

My assumption would be that (without any optimization) we’d end up with the following

Console.WriteLine(s != null ? (s.Name != null ? s.Name.Length : 0) : 0);
Console.WriteLine(s != null ? s.Name : null);

Or, would if magically create code like this

object o = null;
int? l = null;

if (s != null)
{
   o = s.Name;
   if (s.Name != null)
   {
      l = s.Name.Length;
   }
}

Console.WriteLine(l);
Console.WriteLine(o);

With the first snippet of code, a best case scenario results in the IF statement being called twice (when s is null), the worst case (when nothing is null) is that the IF statement will be called three times. Whereas the second example would have the IF called once (when s is null) and twice in the worst case (when nothing is null).

Ofcourse the easiest way to see what happens is to fire up ILSpy and take a look at the generated IL/C# code. Here’s the C# that ILSpy created for us based upon the IL

object obj;
if (s == null)
{
   obj = null;
}
else
{
   string name = s.Name;
   obj = ((name != null) ? new int?(name.Length) : null);
}
Console.WriteLine((int?)obj);
Console.WriteLine((s != null) ? s.Name : null);

In this code, the best case (when s is null), the IF statement is called twice and worst case (when nothing is null), it’s called three times.

This is a simple example, but it’s worth being aware of what code is being produced using such syntactic sugar.