Xamarin.Tip – iOS Push Notification Device Token Extraction in iOS 13+

This weekend, I spent some time getting some apps updated with the latest Xamarin, iOS, Android, etc. A lot of these apps make use of push notifications across platforms. I was running some automated tests against them to do the following steps:

  • Register for push notifications on sign-in / startup
  • Send registration update details to API
  • API sends updates to Azure Notification Hub or Firebase (depends on the project)
  • Send push notification to all test users
  • Send push notification to specific test user

I noticed immediately that all my new iOS builds were failing to receive any push notifications after updating registrations.

Time to debug!

The Old Way

Here was my original method for kicking off the push notification registration:

AppDelegate.cs

//...
private void RegisterForPush()
{
    if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
    {
        UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
            (granted, error) =>
            {
                if (granted)
                    InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
            });
    }
    else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
    {
        var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
                UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
                new NSSet());

        UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
        UIApplication.SharedApplication.RegisterForRemoteNotifications();
    }
    else
    {
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
        UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
    }
}
// ..

This processes kicks off the internal iOS process to start registration. It will check against your apps registered entitlements for push, check the environment it should be using between development and production, and then if all goes well, it will hit the RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) method in the AppDelegate. If there are any explicit errors it will instead hit FailedToRegisterForRemoteNotifications(UIApplication application, NSError error).

So what we need is the data within that deviceToken of the RegisteredForRemoteNotifications method to send to our API.

Here is what the ORIGINAL implementation looked like (with some of the abstractions removed for simplicity):

AppDelegate.cs

// non-user registration
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    // if using default registration with notification hub for non-user apps
    Hub = new SBNotificationHub("{CONN_STRING}", "{AZURE_HUB_NAME}");

    Hub.UnregisterAll(deviceToken, (error) =>
    {
        if (error != null)
        {
            System.Diagnostics.Debug.WriteLine("Error calling Unregister: {0}", error.ToString());
            return;
        }

        NSSet tags = null; // create tags if you want
        Hub.RegisterNativeAsync(deviceToken, tags);

    });
}

And for handling specific user registration, we need to send it to the API:

AppDelegate.cs

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    var token = deviceToken?.Description?.Trim('<', '>')?.Replace(" ", string.Empty);
    if (!string.IsNullOrEmpty(token))
    {
        // this sends the handle to the API to do all the registration
        var remoteRegistrar = new RemoteNotificationRegistrar();
        remoteRegistrar.RegisterForPushAsync("apns", token);
    }
}

Debugging showed me the issue was here:

var token = deviceToken?.Description?.Trim('<', '>')?.Replace(" ", string.Empty);

The token was no longer in the same format… Feeling like an idiot who has been out of the loop, I hit the internet to see what I missed and landed on some of these lovely articles and posts:

So lets do this update in Xamarin:

The New Way

So the old token structure looked like this:

And the new token looks like this:

{length = 32, bytes = 0x965b251c 6cb1926d e3cb366f dfb16ddd ... 5f857679 376eab7c }

So basically we need a clean version of that bytes property of the NSData object.

Azure notification hubs already do this behind the scenes, but we need the clean version for our own method to send to our API, so here’s the new version:

AppDelegate.cs

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    var token = ExtractToken(deviceToken);
    if (!string.IsNullOrEmpty(token))
    {
        // this sends the handle to the API to do all the registration
        var remoteRegistrar = new RemoteNotificationRegistrar();
        remoteRegistrar.RegisterForPushAsync("apns", token);
    }
}

private string ExtractToken(NSData deviceToken)
{
    if (deviceToken.Length == 0)
        return null;
    var result = new byte[deviceToken.Length];
    System.Runtime.InteropServices.Marshal.Copy(deviceToken.Bytes, result, 0, (int)deviceToken.Length);
    return BitConverter.ToString(result).Replace("-", "");
}

There are a few different ways to write this ExtractToken method, but this is what has worked for me!.

After making this change and running it on iOS 13, I started getting user notifications again!

Both Ways

This is great and all, but I still want to make sure folks who haven’t updated to iOS 13 can still use my apps, so I added some explicit version checks to decide which way to extract the token. Here’s what the final looks like all within that ExtractToken method:

private string ExtractToken(NSData deviceToken)
{
    if(UIDevice.CurrentDevice.CheckSystemVersion(13,0))
    {
        if(deviceToken.Length > 0)
        {
            var result = new byte[deviceToken.Length];
            Marshal.Copy(deviceToken.Bytes, result, 0, (int)deviceToken.Length);
            return BitConverter.ToString(result).Replace("-", string.Empty);
        }
    }
    else 
    {
        return deviceToken?.Description?.Trim('<', '>')?.Replace(" ", string.Empty);
    }

    return null;
}

And that’s it! Try this out if you’re having issues with the latest iOS 13 update and your push notification registration.

If you’re still having problems with push notification registration in general, leave a comment below! I’d love to put together an article about the common pitfalls of push notifications on both iOS and Android with a checklist of things to look at, fix, or build on top of what you have!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


CodeMash 2020 This Week!

This week I’ll be at CodeMash – an amazing developer event at the Kalahari Resort in Ohio. CodeMash holds a special place in my heart; It’s the first developer conference I ever attended, the first I ever sponsored, and now I have the honor of being a speaker!

This year, I’ll be talking more about Kotlin for C# developers, and you can catch the session at 9:15 am on Thursday.

Annotation 2020-01-06 113339

If you’re looking to expand your language portfolio with something familiar yet new as a C# developer, you’re going to love this session. Learn about the Kotlin programming language side-by-side with C#, compare and contrast both languages’ amazing features and tooling and walk away with the confidence to to explore and build more with both languages and stacks.

Check out the schedule and other speakers here: https://www.codemash.org/

If you’re at the conference or the area, let me know! I’d love to chat.


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Meadow.Tip – Playing Jingle Bells with a Piezo Speaker Using C#

I was lucky enough to be one of the early backers of the new Meadow board series from Wilderness labs and have since received my board as well as Hack Kit Pro! In this series, I explore and share some of the things I built for fun or for real. Check out wilderness labs here: https://www.wildernesslabs.co/

Playing Jingle bells

One of the basic samples of using the Meadow.Foundation SDK was playing a single note on repeat using a Piezo speaker. Peep that here: https://github.com/WildernessLabs/Meadow.Foundation/tree/master/Source/Samples/Speakers/PiezoSpeaker_Sample

Where the main class that implements the communication to the speaker is:

public class PiezoSpeakerApp : App<F7Micro, PiezoSpeakerApp>
{
    readonly IDigitalOutputPort port;
    readonly IPwmPort pwm; 
    readonly PiezoSpeaker piezoSpeaker;

    public PiezoSpeakerApp()
    {
        pwm = Device.CreatePwmPort(Device.Pins.D05);
        piezoSpeaker = new PiezoSpeaker(pwm);

        TestPiezoSpeaker();
    }

    protected void TestPiezoSpeaker()
    {
        while (true)
        {
            Console.WriteLine("Playing A4 note!");
            piezoSpeaker.PlayTone(440, 1000);
            piezoSpeaker.StopTone();
            Thread.Sleep(500);
        }
    }
}

The application builds a reference to the Piezo speaker through the Digital 05 port and ground, then proceeds to blast the A4 note on repeat until your ears bleed. This is a nice tool to use to make sure your circuit is setup properly, but I wasn’t satisfied…

As a musician, I’m always on the hunt for pleasant notes, little riffs, chords, etc. So naturally, I started looking up some note frequencies I didn’t know off the top of my head and stringing them together.

One of the first songs guitarists learn when first picking at strings and learning the fretboard is Jingle Bells! So what a great way to teach myself how to develop basic melodies using a single output speaker and my brand new Meadow F7 Micro! With that in mind, you can find the entire source for the app here: https://github.com/SuavePirate/Meadow-Piezo-JingleBells

And here’s the guts of the main jingle bells class for the meadow app:

JingleBellsApp.cs

public class JingleBellsApp : App<F7Micro, JingleBellsApp>
{
    readonly PiezoSpeaker piezoSpeaker;

    const int LENGTH = 26;
    const string NOTES = "eeeeeeegcde fffffeeeeddedg";
    readonly int[] BEATS = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 };
    const int TEMPO = 300;

    public JingleBellsApp()
    {
        piezoSpeaker = new PiezoSpeaker(Device.CreatePwmPort(Device.Pins.D05));

        PlayJingleBells();
    }

    protected void PlayJingleBells()
    {
        while (true)
        {
            Console.WriteLine("Playing jingle bells!");
            for (int i = 0; i < LENGTH; i++)
            {
                if (NOTES[i] == ' ')
                {
                    Thread.Sleep(BEATS[i] * TEMPO); // rest
                }
                else
                {
                    PlayNote(NOTES[i], BEATS[i] * TEMPO);
                }

                // pause between notes
                Thread.Sleep(TEMPO / 2);
            }
            Console.WriteLine("From the top!");
        }
    }
    void PlayNote(char note, int duration)
    {
        char[] names = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
        int[] tones = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

        // play the tone corresponding to the note name
        for (int i = 0; i < names.Length; i++)
        {
            if (names[i] == note)
            {
                piezoSpeaker.PlayTone(tones[i], duration);
            }
        }
    }
}

I wanted to make the song more configurable, so I broke the melody out into the notes as a string, and the beats for the song to go along with it. You can also play with the TEMPO to speed things up or slow them down. I also built a private PlayNote method that takes in the major note character and the duration and executes the MeadowFoundation piezoSpeaker.PlayTone to execute the tone on the speaker that was initialized earlier in the contstructor.

So with all these things together, the PlayJingleBellsMethod() takes those constant values and the initialized piezoSpeaker and infinitely loops the entire song. Within the while loop, we use a for loop to play the number of beats that we registered in the LENGTH const and proceed to pull out the beats and notes from the arrays above to string the song together.

When setting up the circuit for your Piezo speaker, just make sure you have the black wire to ground on your board, and red to the port you registered in your constructor (in this case D05). Here’s a fritzing diagram of a simple setup for it:

jinglebells_spiezo_bb

That’s all there is to it! Stay tuned for more fun projects and how to setup them up as I keep working through how to build some different fun things with my new Meadow board!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Techorama This Week – Kotlin, C#, Flux, Design Patterns, and more!

If you’re in the Netherlands this week, come catch me at Techorama! I’ll be there from the 30th through the 3rd of October and presenting two different sessions:

techorama_sessions

On the 1st, I’ll be speaking on Kotlin for C# Developers:

Dive into the latest craze in languages and platforms – Kotlin. This time we will be looking at it from the perspective of a .NET C# developer, draw comparisons between the languages, and bridge the gap between these 2 amazing languages. We’ll look at: – Kotlin as a language – Platforms Kotlin is great for – Object Oriented Implementations in Kotlin – Extended Features – Features Kotlin has that C# doesn’t – A demo Android application in Kotlin vs a Xamarin.Android app in C# In the end you will leave with a foundational knowledge of Kotlin and its capabilities to build awesome apps with less code. You should feel comfortable comparing C# applications to Kotlin applications and know where to find resources to learn even more!
And on the 2nd I have another morning session on implementing the Flux design pattern in C# and .NET:
Learn about the Flux design pattern and how to implement it in your C# client applications like UWP, Xamarin, and all the other platforms .NET is touching now. We’ll compare Flux and Uni-Directional data flows to the existing tools and directions development takes us in C# client apps and talk about all the pros and cons that come with both. We’ll take an existing Xamarin.Forms app using MVVM and “Flux it Up” to migrate to a more 1-direction flow of data and actions. When you leave, you’ll have a solid understanding of Flux and some of its existing implementations such as Redux and be confident in implementing it yourself in C#!

Pre-conference Meetup

If you’re not going to Techorama this year, but are still in the area, you can find me tomorrow at the Dutch Mobile .NET Developers meetup with some of the other amazing people from the Xamarin and .NET Community. I’ll be on a panel talking about mobile technologies and practices!

https://www.meetup.com/Dutch-Mobile-NET-Developers-Group/events/262894590/

 

Here’s the schedule:

18:00 Doors open & Dinner
19:00 – 20:00 The Latest and Craziest for Mobile .NET Developers
David Ortinau @davidortinau
Microsoft has been hard at work improving Visual Studio and Xamarin for mobile developers. I’ll demo the latest features you can use to make your dev experience better today. And in the future? Microsoft has some “coming soon” as well as highly experimental projects that are “must see”!

20:00 – 20:15 Break
20:15 – 21:00 Mobile Expert Panel with Alex, Brandon, Dan & Gerald
Open Q&A for these mobile experts that have absolutely made their mark in the mobile developer space. This is your chance to ask anything you’d like! Joining us are:

Alex Dunn @suave_pirate
Author at Pluralsight | Xamarin MVP | Microsoft MVP

Brandon Minnick @thecodetraveler
Microsoft Developer Advocate | Mobile App Developer

Dan Siegel @danjsiegel
Microsoft MVP | @PrismLib Maintainer | Xamarin Evangelist | @XamDevSummit Organizer

Gerald Versluis @jfversluis
Engineer @Microsoft for #XamarinForms | Former Microsoft MVP

21:00 Drinks & Closing

 

See ya’ll there!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Video – Kotlin for C# Developers at NDC Oslo

In June, I had the amazing privilege of giving a talk at NDC Oslo called “Kotlin for C# Developers”! Lucky for you, NDC records all of their sessions, so you can check out the recording from YouTube right here 🙂

Dive into the latest craze in languages and platforms – Kotlin. This time we will be looking at it from the perspective of a .NET C# developer, draw comparisons between the languages, and bridge the gap between these 2 amazing languages.

We’ll look at:
– Kotlin as a language
– Platforms Kotlin is great for
– Object Oriented Implementations in Kotlin
– Extended Features
– Features Kotlin has that C# doesn’t
– A demo Android application in Kotlin vs a Xamarin.Android app in C#

In the end you will leave with a foundational knowledge of Kotlin and its capabilities to build awesome apps with less code. You should feel comfortable comparing C# applications to Kotlin applications and know where to find resources to learn even more!

Let me know your thoughts in the comments or on Twitter, and check out my other content on Kotlin here: https://alexdunn.org/tag/kotlin/

Want to see this live? I’ll be giving an updated version of this talk at Techorama Netherlands in September/October along with an introduction to the Flux design pattern in C#.

Check those out here:

If you prefer to just jump right into a language / platform – I would happily suggest my Pluralsight course – Building Android Apps with Kotlin: Getting Started. Take a look here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/

 

 


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Conversation Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Alexa.Tip – Build Unit Tested Skills in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts, design patterns, and implementations that developers might not be aware of, and how they can be applied to voice application development, best practices, and more!

In this post, we explore some more best practices in developing Alexa Skills in C# whether you are using an ASP.NET Core API or an AWS Lambda. This post will expand our previous posts about building better abstractions for handling Alexa responses and demonstrate how we can now properly Unit test these handlers as well as any other separated bits of logic that the Handler implementations consume.

Check out all the raw source code for this post, and more here: https://github.com/SuavePirate/Alexa.Tips.Net

Prerequisite

If you haven’t read up on how to use the Handler Registration Pattern, take a look at my earlier post here: Alexa.Tip – Using Handler Registration Pattern in .NET

The short version is that we use this pattern of registering IHandler implementations to handle different types of requests that our skill receives, regardless of whether we are using AWS Lambdas or ASP.NET Core APIs.

Unit Testing Handlers

Since we now have nice atomized units (Handlers) built for each of our RequestTypes and Intents, they are SCREAMING to be unit tested. So, we can easily test them against different scenarios given our positive and negative cases.

Take for example, the SimpleLaunchHandler that is responsible only for LaunchRequest, and whose HandleAsync() implementation returns a static response. The two main cases we want to test against is the HandleAsync() returning properly for a proper LaunchRequest, and that the CanHandle() implementation returns false for non LaunchRequest skill requests.

In these samples, I’m using xUnit for my Unit tests, but the same concept is applicable with any other Unit testing framework (and really any other language).

In each case, we want to separate our 3 A’s of testing, “Arrange”, “Act”, and “Assert”. For these basic examples, the three steps are pretty clear.

  1. Arrange the Testable SkillRequest object
  2. Act on the subject’s method we are testing by sending it the SkillRequest
  3. Assert our final response

Let’s first test the CanHandle() against the postive case, meaning we want to send it data we want to be successful:

public class SimpleLaunchHandlerTests
{
    private readonly SimpleLaunchHandler _subject;
    public SimpleLaunchHandlerTests()
    {
        _subject = new SimpleLaunchHandler();
    }


    [Fact]
    public void SimpleHandler_CanHandleLaunchRequest()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new LaunchRequest
            {
                Type = "LaunchRequest"
            }
        };

        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.True(canHandle);
    }

}

Now let’s perform the opposite by sending it a request of a different type:

 [Fact]
public void SimpleHandler_CanNotHandleIntentRequest()
{
    // arrange
    var request = new SkillRequest()
    {
        Version = "1.0",
        Request = new IntentRequest
        {
            Type = "IntentRequest"
        }
    };

    // act
    var canHandle = _subject.CanHandle(request);

    // assert
    Assert.False(canHandle);
}

Now, we can look at the positive example of passing the LaunchRequest into the HandleAsync method:

[Fact]
public async Task SimpleHandler_ReturnsResponse()
{
    // arrange
    var request = new SkillRequest()
    {
        Version = "1.0",
        Request = new LaunchRequest
        {
            Type = "LaunchRequest"
        }
    };

    // act
    var response = await _subject.HandleAsync(request);

    // assert
    Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
}

Now that we have our LaunchRequest tested, let’s take a look at a simple static IntentRequest set of tests:

DogFactHandlerTests.cs

public class DogFactHandlerTests : IClassFixture<DogFactHandler>
{
    private readonly DogFactHandler _subject = new DogFactHandler();


    [Fact]
    public async Task DogFactHandler_ReturnsResponse()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };

        // act
        var response = await _subject.HandleAsync(request);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }

    [Fact]
    public void DogFactHandler_CanHandleIntentRequest()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };
        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.True(canHandle);
    }
    [Fact]
    public void DogFactHandler_CanNotHandleLaunchRequest()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new LaunchRequest
            {
                Type = "LaunchRequest"
            }
        };


        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.False(canHandle);
    }
    [Fact]
    public void DogFactHandler_CanNotHandleOtherIntents()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "AMAZON.HelpIntent"
                }
            }
        };


        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.False(canHandle);
    }
}

Okay, cool, but what about stuff that isn’t static? What if I’m getting my data from somewhere else and want to test those cases? Let’s bring Moq into the picture!

Let’s take this handler for example:

SampleFactHandler.cs

public class SampleFactHandler : GenericHandler, IHandler
{
    private readonly SampleMessageDbContext _context;
    public SampleFactHandler(SampleMessageDbContext context)
    {
        _context = context;
    }
    public override string IntentName => "SampleMessageIntent";

    public override Type RequestType => typeof(IntentRequest);

    public override async Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        // just grab one as an example
        var message = await _context.SampleMessages.FirstOrDefaultAsync();
        return ResponseBuilder.Tell(message?.Content ?? "I don't have any messages for you.");
    }
}

So this Handler uses an Entity Framework Core DbContext with a table of SampleMessage objects to get the content. In this sample, we just grab the first one, but you could imagine some more complex data-logic to pull out the proper message.

To unit test this, we can pass in different “Mock” implementations of the SampleMessageDbContext. For this, I usually use Moq, but you can also pass in a full implementation that you’ve built yourself.

Here are some samples of testing this with different Moq’d contexts to test a few scenarios. Note: we still want to test against the CanHandle and HandleAsync as well, but now we have two different cases to test for such as if there are no messages in the db, and when there is one.

SampleFactHandlerTests.cs

public class SampleFactHandlerTests
{
    [Fact]
    public async Task SampleFactHandler_ReturnResponseWithData()
    {
        // arrange
        var context = new Mock<SampleMessageDbContext>();
        context.Setup(d => d.SampleMessages.FirstOrDefaultAsync(CancellationToken.None)).Returns(Task.FromResult(new SampleMessage
        {
            Id = Guid.NewGuid().ToString(),
            Content = "This is a mocked response message"
        }));
        var subject = new SampleFactHandler(context.Object);
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "SampleMessageIntent"
                }
            }
        };

        // act
        var response = await subject.HandleAsync(request);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }
    [Fact]
    public async Task SampleFactHandler_ReturnFallbackResponseWithNoData()
    {
        // arrange
        var context = new Mock<SampleMessageDbContext>();
        context.Setup(d => d.SampleMessages.FirstOrDefaultAsync(CancellationToken.None)).Returns(Task.FromResult<SampleMessage>(null));
        var subject = new SampleFactHandler(context.Object);
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "SampleMessageIntent"
                }
            }
        };

        // act
        var response = await subject.HandleAsync(request);

        // assert
        Assert.True((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text == "I don't have any messages for you.");
    }
}

We can also, and probably should also add some CanHandle and non-assinable Intent types to test, but for the sake of not making you read the same thing over and over again, these are the two that matters.

Unit Testing Controllers

Personally, I don’t typically unit test my Controllers, but that’s because I have some general rules in place to not change them one they are implemented. However, when working on a team, it may be easier and more sustainable to implement a few test on the controller to guarantee that changes made to it don’t affect the currently working implementation.

Some basic positive/negative test might look like this:

SimpleAlexaControllerTests.cs

public class SimpleAlexaControllerTests
{
    [Fact]
    public async Task AlexaController_ResponseWithHandler() 
    {
        // arrange
        var subject = new SimpleAlexaController(new List<IHandler>{ new DogFactHandler() });
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };
        // act
        var response = _subject.HandleRequest(request);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }

    [Fact]
    public async Task AlexaController_ResponseWithoutHandler() 
    {
        // arrange
        var subject = new SimpleAlexaController(new List<IHandler>{ new SimpleLaunchHandler() }); // no DogFactHandler
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };

        // act
        var response = _subject.HandleRequest(request);

        // assert
        Assert.Null(response);
    }
}

Unit Testing Lambda Functions

Just like testing the Controller, if you are using AWS Lambda rather than ASP.NET Core, you can create unit tests against your Function endpoint in order to get some coverage. That could look simple like something here:

FunctionHandlerTests.cs

public class FunctionHandlerTests
{

    [Fact]
    public async Task LambdaFunction_ResponseWithHandler() 
    {
        // arrange
        var subject = new SimpleAlexaHandler();
        subject.Handlers = new List<IHandler>{ new DogFactIntent() });
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };
        // act
        var response = _subject.HandleRequest(request, null);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }

    [Fact]
    public async Task LambdaFunction_ResponseWithoutHandler() 
    {
        // arrange
        var subject = new SimpleAlexaHandler();
        subject.Handlers = new List<IHandler>{ new SimpleLaunchHandler() }); // no DogFactIntent handler
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };

        // act
        var response = _subject.HandleRequest(request);

        // assert
        Assert.Null(response);
    }

}

That’s all the unit test types for now! Anything else that needs testing would be tested outside the Alexa specific logic. But hey! Now we can write some strong and code-covered tested skills which leads to better skills overall

What’s next?

Check out more Alexa Developer Tips here: https://alexdunn.org/tag/alexa/


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Alexa.Tip – Using Dependency Injection with Handlers in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts, design patterns, and implementations that developers might not be aware of, and how they can be applied to voice application development, best practices, and more!

In this post, we explore some more best practices in developing Alexa Skills in C# whether you are using an ASP.NET Core API or an AWS Lambda. This time, we talk about taking our Handler Registration Pattern to the next level by using dependencies in them such as EF DbContexts or really any other service you want to inject.

Check out all the raw source code for this post, and more here: https://github.com/SuavePirate/Alexa.Tips.Net

If you haven’t read up on how to use the Handler Registration Pattern, take a look at my earlier post here: Alexa.Tip – Using Handler Registration Pattern in .NET

The short version is that we use this pattern of registering IHandler implementations to handle different types of requests that our skill receives, regardless of whether we are using AWS Lambdas or ASP.NET Core APIs.

Building Handlers with Dependencies

So we’ve seen samples of simple Handlers that use static responses simply using the ResponseBuilder from the Alexa.NET Library, but now let’s take it to the next logical step and start to get some data from a database. In this case, I am using Entity Framework, and therefore need to access my DbContext to get data.

To do this, we should inject the DbContext, in this case a SampleMessageDbContext into the constructor of the SampleFactHandler, then use it locally in the HandleAsync() method to get a single message.

SampleFactHandler.cs

public class SampleFactHandler : GenericHandler, IHandler
{
    private readonly SampleMessageDbContext _context;
    public SampleFactHandler(SampleMessageDbContext context)
    {
        _context = context;
    }
    public override string IntentName => "SampleMessageIntent";

    public override Type RequestType => typeof(IntentRequest);

    public override async Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        // just grab one as an example
        var message = await _context.SampleMessages.FirstOrDefaultAsync();
        return ResponseBuilder.Tell(message?.Content ?? "I don't have any messages for you.");
    }
}

Although this simple example just grabs the first row from the db for the SampleMessages table, you could imagine some more complex data logic applied here to find the proper response we want for the given request. I also added some quick null handling just to clean it up for a real sample.

Registering Handlers with Dependencies

Now that we have our SampleFactHandler, we need to register it to our ICollection, but also construct it using the SampleMessageDbContext. There are a couple ways to do this. For simple situations, you just need to register the DbContext in your Startup, then grab it from the ServiceCollection when creating the List:

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // add other dependencies first
        services.AddDbContext<SampleMessageDbContext>(options =>
        {
            options.UseInMemoryDatabase("InMemoryDbForTesting");
        });

        // Register your handlers here!
        services.AddScoped<ICollection<IHandler>>(s =>
        {
            // get the db context to inject in the handlers that are dependent
            var dbContext = s.GetRequiredService<SampleMessageDbContext>();
            return new List<IHandler>
            {
                new SimpleLaunchHandler(),
                new DogFactHandler(),
                new SampleFactHandler(dbContext)
            };
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

Alternatively, you could create a class whose responsibility is to hold onto the handlers and construct that list with all the IHandlers. Something like this:

IHandlerContainer.cs

public interface IHandlerContainer
{
    ICollection<IHandler> Handlers { get; }
}

HandlerContainer.cs

public class HandlerContainer : IHandlerContainer 
{
    public ICollection<IHandler> Handlers { get; private set; }
    public HandlerContainer(SimpleLaunchHandler launch, DogFactHandler dogFact, SampleFactHandler sampleFact)
    {
        Handlers = new List<IHandler> { launch, dogFact, sampleFact }
    }
}

With this container, we update our Startup to look something like this:

 public void ConfigureServices(IServiceCollection services)
    {
        // add other dependencies first
        services.AddDbContext<SampleMessageDbContext>(options =>
        {
            options.UseInMemoryDatabase("InMemoryDbForTesting");
        });
        services.AddScoped<SimpleLaunchHandler>();
        services.AddScoped<DogFactHandler>();
        services.AddScoped<SampleFactHandler>();
        services.AddScoped<IHandlerContainer, HandlerContainer>();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

Then our Controller would consume the IHandlerContainer rather than a flat ICollection to look like this:

SimpleAlexaController.cs

[Route("[controller]")]
public class SimpleAlexaController : Controller
{
    private readonly IHandlerContainer _handlerContainer;
    public SimpleAlexaController(IHandlerContainer handlerContainer)
    {
        _handlerContainer = handlerContainer;
    }
    [HttpPost]
    public async Task<SkillResponse> HandleRequest([FromBody]SkillRequest request)
    {
        var viableHandler = _handlerContainer.Handlers.FirstOrDefault(h => h.CanHandle(request));
        return await viableHandler.HandleAsync(request);
    }
}

I think this little pattern helps cleanup the Startup without needing to explicitly pull dependencies out of the ServiceCollection in order to build the IHandlers. Which do you prefer?

What’s next?

In future posts, we’ll take a look at building on these types of handlers with things like:

  • Well written Unit Tests
  • Full Integration Tests
  • Advanced Contextual driven handlers

If there’s enough interest in this pattern and the tools I’m building around it, let me know in GitHub or Twitter and I’ll work on getting them into properly libraries and NuGet packages 🙂

Check out more Alexa Developer Tips here: https://alexdunn.org/tag/alexa/


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Alexa.Tip – Using Handler Registration Pattern in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts, design patterns, and implementations that developers might not be aware of, and how they can be applied to voice application development, best practices, and more!

In this post, we explore some more best practices in developing Alexa Skills in C# whether you are using an ASP.NET Core API or an AWS Lambda. This time, we talk about using the Registration Pattern for our Request Handlers. This post builds off of some of the concepts found in a previous post: Alexa.Tip – Build Intent Handlers in .NET but uses a newer abstraction tactic I like that can be found in my Alexa .NET Samples Repo here: https://github.com/SuavePirate/Alexa.Tips.Net

If you followed the previous post, you saw the benefits of abstracting our Alexa specific business logic into Handlers. That post talked specifically about IntentHandlers, but I’ve gone about implementing a new pattern for handling all request types that follows some of the same patterns of the official Alexa Skills Kit SDKs in JavaScript and Java but with all the C# goodness of Dependency Injection, Abstractions, async, and more.

Build Handlers

The primary concept is to create Handlers that register with information about what types of requests they can handle, then register those handlers for Dependency Injection (but in a slightly different way than normal), then finding the proper Handler for the given request and passing the rest of the transaction off to it to run its logic.

Here’s a look at our foundation: the IHandler:

IHandler.cs

public interface IHandler
{
    Type RequestType { get; }
    string IntentName { get; }
    bool CanHandle(SkillRequest request);
    Task<SkillResponse> HandleAsync(SkillRequest request);
}

So with this, we can use RequestType to validate what type of request the handler is for such as LaunchRequest or IntentRequest. You can take a peep at all the request types of Alexa Skills here: https://developer.amazon.com/docs/custom-skills/request-types-reference.html

We can also use the IntentName to easily assign a specific intent to a handler if the RequestType is IntentRequest. Then CanHandle() is used for applying custom validation logic to tell the registration what type of requests it is for. An implementation of this might validate the RequestType and IntentName while still allowing a specific Handler to apply its own logic to whether it can handle the request or not such as checking sessionAttributes or Context.

To handle this abstraction, I implemented an abstract class to implement the default CanHandle:

GenericHandler.cs

public abstract class GenericHandler : IHandler
{
    public abstract string IntentName { get; }
    public abstract Type RequestType { get; }
    public abstract Task<SkillResponse> HandleAsync(SkillRequest request);
    public virtual bool CanHandle(SkillRequest request)
    {
        if (request.GetRequestType() != RequestType)
            return false;
        if(request.GetRequestType() == typeof(IntentRequest))
        {
            if ((request?.Request as IntentRequest)?.Intent?.Name != IntentName)
                return false;
        }
        return true;
    }
}

If you are using C# 8 (I’m not in this case because its in preview at time of writing this), you can just use the Default Interface Implementation feature instead of using this extra abstract class at all. So your IHandler would look like this:

IHandler.cs

public interface IHandler
{
    Type RequestType { get; }
    string IntentName { get; }
    Task<SkillResponse> HandleAsync(SkillRequest request);
    bool CanHandle(SkillRequest request)
    {
        if (request.GetRequestType() != RequestType)
            return false;
        if(request.GetRequestType() == typeof(IntentRequest))
        {
            if ((request?.Request as IntentRequest)?.Intent?.Name != IntentName)
                return false;
        }
        return true;
    }
}

The last bit is the actual HandleAsync() which is just used to actually process the request and build a response to send back to Alexa.

So let’s look at a real implementation with the most simple example I can think of.

SimpleLaunchHandler.cs

public class SimpleLaunchHandler : GenericHandler, IHandler
{
    public override string IntentName => null;

    public override Type RequestType => typeof(LaunchRequest);

    public override Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        return Task.FromResult(ResponseBuilder.Ask("Welcome to abstracted .NET Alexa Skills. How can I help?", null));
    }
}

Request type of LaunchRequest because we are handling the welcome message of the skill. We don’t override the CanHandle because we only care about the RequestType, and then the HandleAsync just returns a result task with a simple text-only response welcoming the user.

Here’s an example of a basic Intent Handler for a specific intent:

DogFactHandler.cs

public class DogFactHandler : GenericHandler, IHandler
{
    public override string IntentName => "DogFactIntent";

    public override Type RequestType => typeof(IntentRequest);

    public override Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        return Task.FromResult(ResponseBuilder.Tell("Dogs do in fact have a sense of time, and even miss you when you're gone."));
    }
}

Just like the SimpleLaunchHandler, we set the RequestType but instead to IntentRequest, then supply the name of the Intent we want to handle.

Find and Execute Handlers

Now that we have some implementations of IHandlers, we can register them to use in our actual skill. The general idea is to create the collection of these handlers, then find the correct one to use given the type of request and execute it.

In it’s simplest form, we have a collection of handlers:

var handlers = new List<IHandler> { new SimpleLaunchHandler(), new DogFactHandler() };

Then find the right one to use:

var foundHandler = handlers.FirstOrDefault(h => h.CanHandle());

Then execute it:

var response = await foundHandler.HandleAsync(request);

Implement in ASP.NET Core

Let’s take a look at a real sample of how to do this using ASP.NET Core as if we were using HTTPS as our fulfillment URL of our skill rather than an AWS Lambda ARN.

First thing we should do is register our IHandlers for dependency injection in our Startup:

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Register your handlers here!
        services.AddScoped<ICollection<IHandler>>(s =>
        {
            return new List<IHandler>
            {
                new SimpleLaunchHandler(),
                new DogFactHandler()
            };
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
            app.UseDeveloperExceptionPage();
        else
            app.UseHsts();

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

Now we can create a Controller that consumes an ICollection in the constructor. Alternatively, you can also register the IHandlers independently and then build the collection in the constructor of the Controller instead, but I kinda like this way better.

SimpleAlexaController.cs

[Route("[controller]")]
public class SimpleAlexaController : Controller
{
    private readonly ICollection<IHandler> _handlers;
    public SimpleAlexaController(ICollection<IHandler> handlers)
    {
        _handlers = handlers;
    }
    [HttpPost]
    public async Task<SkillResponse> HandleRequest([FromBody]SkillRequest request)
    {
        var viableHandler = _handlers.FirstOrDefault(h => h.CanHandle(request));
        return await viableHandler.HandleAsync(request);
    }
}

And that’s it! Now we can send requests to our /SimpleAlexa/ endpoint and use the handlers we registered. As we add more functionality to our Skill, we just create new IHandlers and add them to the Startup registration.

Implement in Lambda

So you might already know that Lambda functions don’t really play well with dependency injection outside of building a simple service locator, and their recommended practice is to build your code all in the lambda (yucky for us C# devs) or build your depdendent classes all at the beginning of executing the function. For this scenario, I like to have a single method for building my primary dependency (in this case, it’s the list of handlers again!). So our full Lambda Function code might looke like this:

Function.cs

public class Function 
{
    public async Task FunctionHandler(SkillRequest request, ILambdaContext context)
    {
        var viableHandler = BuildHandlers().FirstOrDefault(h => h.CanHandle(request));
        return await viableHandler.HandleAsync(request);
    }

    private ICollection<IHandler> BuildHandlers()
    {
        return new List<IHandler> { new SimpleLaunchHandler(), new DogFactHandler() };
    }
}

What’s next?

This is a pretty neat design pattern I’ve been working out in some custom Alexa Skills to help scale the codebase of more complex scenarios. These samples are quite simple, but hopefully convey how easy it is to get setup with this pattern, and start to get you thinking about ways to build ontop of this pattern.

In future posts, we’ll take a look at building on these types of handlers with things like:

  • Well written Unit Tests
  • Full Integration Tests
  • Using Entity Framework
  • Using multi-level dependency injection
  • Advanced Contextual driven handlers

If there’s enough interest in this pattern and the tools I’m building around it, let me know in GitHub or Twitter and I’ll work on getting them into properly libraries and NuGet packages 🙂

Check out more Alexa Developer Tips here: https://alexdunn.org/tag/alexa/


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


NDC Oslo Coming Up!

Just a quick post today to tell you all how excited I am for the next event I’ll be at:

NDC, one of my absolute favorite conference series is going to be running their original NDC Oslo conference in the next couple weeks! As always, I’m so humbled to be among some of the most amazing people in the Software industry that I personally have learned so much from. I hope to be able to share my experiences and learnings with you all in return!

I’ll be speaking about two of my favorite programming languages, Kotlin and C#! If you’re a C# developer and are interested in learning more about Kotlin and what’s been going on with one of the hottest new languages, come check out my session where we will intro Kotlin, compare features of the language, and even talk about how they might play well together in the future! If you don’t come for the languages, come for the stickers! I’m coming in hot with some awesome Kotlin, Xamarin, and C# stickers.

If you aren’t coming to NDC Oslo, be sure to check out my Kotlin posts here as well as check out my course on Pluralsight – Building Andorid Apps with Kotlin: Getting Started to learn about how to apply Kotlin to building native Android apps with the latest and greatest tools!

You can also checkout an older version of my Kotlin for C# Developers talk from NDC London here. https://www.youtube.com/watch?v=pR8zPYlNU0k

Can’t wait! See you there!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Clean Up Your Client to Business Logic Relationship With a Result Pattern (C#)

If you’ve been developing well structured and scalable code bases, you probably focus a whole lot on your “Separation of Concerns”. Maybe you implement a design pattern or code architectures like SOLID, Clean, or Onion to enforce some stricter rules around those separations.

In the .NET world, we use a lot of Inversion of Control and Dependency Injection. Especially in ASP.NET Core. However, I find that a lot of implementations are still missing one big separation – error handling.

The most common case I see in a decently structured application is:

  • Controller injects a service
  • Service runs business logic
  • On error, service throws exception
  • Controller exposes that an error happened via catching exception

One problem I have with this is that the Controller is now handling some business logic by managing the error. So what is my proposal? Handle your business logic errors / validation and expose the result of that logic, whether successful or with errors, to the controller that then determines the proper HTTP Response Code and message to return based on the type of result.

This is often just called the Result Pattern but I think it goes beyond this concept when wrapping it up into something like CLEAN or Onion. So, I often refer to it as the Service Result Pattern. I typically employ this pattern in all of my applications – back end and front end alike.

Here is what it looks like in C#. We want to create a Result object that our business logic will return to our Controller, ViewModel, View, etc. Samples here will be referring to an ASP.NET Core 2.1 RESTful API implementation, but the pattern can be applied everywhere.

So we need:
– Result classes
– A controller that returns IActionResult
– A business logic class that returns a Result
– Validation and error handling logic

The Result Model

I’ve created a NuGet package for these Result models if you want to use those, but these are the essentials duplicated here if you want to do it yourself. The package can be found here:

NuGet: https://www.nuget.org/packages/ServiceResult/
GitHub: https://github.com/SuavePirate/ServiceResult

First we want an abstract Result class that contains the data, errors, and the type. Then we can create child types that can make the typing of our results stronger.

Result.cs

public abstract class Result<T>
{
    public abstract ResultType ResultType { get; }
    public abstract List<string> Errors { get; }
    public abstract T Data { get; }
}

ResultType.cs

public enum ResultType
{
    Ok,
    Invalid,
    Unauthorized,
    PartialOk,
    NotFound,
    PermissionDenied,
    Unexpected
}

The idea is that for each one of these result types, we should have a strongly typed implementation. Here are a few examples of the most commonly used ones.

InvalidResult.cs

public class InvalidResult<T> : Result<T>
{
    private string _error;
    public InvalidResult(string error)
    {
        _error = error;
    }
    public override ResultType ResultType => ResultType.Invalid;

    public override List<string> Errors => new List<string> { _error ?? "The input was invalid." };

    public override T Data => default(T);
}

UnexpectedResult.cs

public class UnexpectedResult<T> : Result<T>
{
    public override ResultType ResultType => ResultType.Unexpected;

    public override List<string> Errors => new List<string> { "There was an unexpected problem" };

    public override T Data => default(T);
}

SuccessResult.cs

public class SuccessResult<T> : Result<T>
{
    private readonly T _data;
    public SuccessResult(T data)
    {
        _data = data;
    }
    public override ResultType ResultType => ResultType.Ok;

    public override List<string> Errors => new List<string>();

    public override T Data => _data;
}

Notice how the only one that implements Data as anything other than default(T) is the SuccessResult. This guarantees us our data is consistent based on the result type and we can instead use different error types to map the proper error messages, ResultType, etc.

Using the Result in Business Logic

Let’s take a look at a sample of how we can use these models in our business logic to house all our success and error logic.

MyService

public class MyService : IMyService
{
    private readonly IMyRepository _repository;
    private readonly IPermissionService _permissions;

    public MyService (IMyRepository repository, IPermissionService permissions)
    {
        _repository = repository;
        _permissions = permissions;
    }

    public async Task<Result<MyDTO>> GetSomethingAsync(string id)
    {
        try
        {
            if(string.IsNullOrEmpty(id))
                return new InvalidResult<MyDTO>("Invalid ID");

            var hasPermission = await _permissions.HasPermissionsToDoSomethingAsync();
            if(!hasPermission)
                return new AccessDeniedResult<MyDTO>();

            var myData = await _repository.FindAsync(id);
            if(myData == null)
                return new NotFoundResult<MyDTO>();

            return new SuccessResult<MyDTO>(new MyDTO(myData));
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex);
            return new UnexpectedResult<MyDTO>();
        }
    }
}

This shows how we can use our different Result classes to step through our business logic in a very flat easy to follow and read way while still managing errors consistently.

Build an IActionResult from a Result

Once we have a Result returned, we want to give our controller the ability to map the type and data to the proper HTTP response. Doing this ensures that our Controller is only responsible for HTTP related logic, and not for business logic.

I’ve done this in the past with either a BaseController or with an extension method. If you want a simple extension method, check out my other NuGet package for it:

NuGet: https://www.nuget.org/packages/ServiceResult.ApiExtensions/
GitHub: https://github.com/SuavePirate/ServiceResult

Here’s what that method would look like:

ControllerExtensions

public static ActionResult FromResult<T>(this ControllerBase controller, Result<T> result)
{
    switch (result.ResultType)
    {
        case ResultType.Ok:
            return controller.Ok(result.Data);
        case ResultType.NotFound:
            return controller.NotFound(result.Errors);
        case ResultType.Invalid:
            return controller.BadRequest(result.Errors);
        case ResultType.Unexpected:
            return controller.BadRequest(result.Errors);
        case ResultType.Unauthorized:
            return controller.Unauthorized();
        default:
            throw new Exception("An unhandled result has occurred as a result of a service call.");
    }
}

With this, our Controller methods can be made extremely clean. Here’s an example:

MyController.cs

public class MyController : Controller
{
    private readonly IMyService _service;
    public MyController(IMyService service)
    {
        _service = service;
    }

    [HttpGet]
    public async Task<IActionResult> GetSomethingAsync(string id)
    {
        var result = await _service.GetSomethingAsync(id);
        return this.FromResult(result);
    }
}

Assuming our _service.GetSomethingAsync() returns a Task we can keep all our endpoints clean and only responsible for being a gateway to our application logic! So clean 😀

Conclusion

All together, we are able to ensure our error logic lives within our application/business logic and that our Controllers are able to worry just about the HTTP side of things. We do a better job at separating our concerns, we keep our business logic flat and easy to follow, and we provide our consumers of our application easy to follow data and errors by ensuring we return the proper HTTP responses and structures.


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.