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/


Advertisements

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/


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.

Seed Your Entity Framework Core Data at Startup with ASP.NET Core 2

If you’re developing large scale database designs using Entity Framework, especially with Code First Migrations, you’ve likely wanted to seed some data. Perhaps it’s some constant lookup values or test data used in your local dev environments for on-boarding new team members. It’s also nice to run migrations on startup for when you are deploying to different environments!

This blog post is just a simple set of tools I commonly use to allow for automatically running migrations and seeding some data with some examples.

Basically we’ll:

  • Design a Code First Database with EF Core
  • Add a migration
  • Build two different Seeder classes
  • Build an extension method to run Migrations and the Seeders when the application starts

This doesn’t care about how you actually setup your DbContext within your app, what database provider you use, etc.

Database Design

Let’s go with a simple example of a Blog website database design. Let’s first add some POCOs for out entities then create our DbContext.

Post.cs

public class Post 
{
    public long Id { get; set; }
    public string Title { get; set;}
    public string Content { get; set; }
    public string PostTypeId { get; set; }
    public virtual PostType PostType { get; set; }
}

PostType.cs

public class PostType
{
    public long Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

BlogContext.cs

public class BlogContext : DbContext 
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<PostType> PostTypes { get; set; }
}

Add Migration

Now that we have a DbContext and our tables, let’s create our migration!

In the Visual Studio Package Manager Console:

add-migration InitialCreate

or in the CLI:

dotnet ef migrations add InitialCreate

Building Seeder Classes

Now we have a database designed and a migration, so let’s create a seeder for creating some PostTypes that should be the same for every environment and then another TestDataSeeder to seed some examples for developers to use when running the app for the first time.

PostTypesSeeder

public class PostTypesSeeder
{
    private readonly BlogContext _context;
    public PostTypesSeeder(BlogContext context)
    {
        _context = context;
    }

    public void SeedData()
    {
        AddNewType(new PostType { Id = 0, Name = "Standard" });
        AddNewType(new PostType { Id = 1, Name = "Aside" });
        AddNewType(new PostType { Id = 2, Name = "Snippet" });
        _context.SaveChanges();
    }

    // since we run this seeder when the app starts
    // we should avoid adding duplicates, so check first
    // then add
    private void AddNewType(PostType postType)
    {
        var existingType = _context.PostTypes.FirstOrDefault(p => p.Name == postType.Name);
        if(existingType == null)
        {
            _context.PostTypes.Add(postType);
        }
    }
}

This seeder let’s us add 3 different PostTypes if they don’t already exist.

TestDataSeeder.cs

public class TestDataSeeder
{
    private readonly BlogContext _context;
    public TestDataSeeder(BlogContext context)
    {
        _context = context;
    }

    public void SeedData()
    {
        _context.Posts.Add(new Post
        {
            Name = "Test Post 1",
            Content = "This is my standard post for testing",
            PostTypeId = 0
        };
        _context.Posts.Add(new Post
        {
            Name = "Test Post 2",
            Content = "This is my aside post for testing",
            PostTypeId = 2
        };

        _context.SaveChanges();
    }
}

Building the WebHost Extension

Now that we have our seeders. Let’s build that extension method for running the migration and running this seeders.

WebHostExtensions.cs

public static class WebHostExtensions
{
    public static IWebHost SeedData(this IWebHost host)
    {
        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            var context = services.GetService<BlogContext>();

            // now we have the DbContext. Run migrations
            context.Database.Migrate();

            // now that the database is up to date. Let's seed
            new PostTypesSeeder(context).SeedData();

#if DEBUG
            // if we are debugging, then let's run the test data seeder
            // alternatively, check against the environment to run this seeder
            new TestDataSeeder(context).SeedData();
#endif
        }
    }
}

Implementing the Extension

Now that we have our database and entities, seeders, and an extension method – let’s just drop it in our Program class to run when we are creating the WebHost!

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().SeedData().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();

}

Note: although this Program is in the ASP.NET Core 2.1 style, the same code works in the original 2.0 style. Just stick it after the Build() call wherever you run that.

And that’s it! Now we have always-up-to-date data whenever we run our ASP.NET Core app! 😀


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.

Alexa.Tip – Build Intent 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 that developers might not be aware of, design patterns that 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 abstracting our business logic out of either our Function or Controller and into separate Handler classes.

If you’ve done skill development in node.js or in .NET, you’ve probably noticed that a lot of docs, example apps, and real world apps are written with one BIG class or file. That’s pretty gross.

You may some C# examples look like this:

UglyFunction.cs

public class Function
{
    public async Task<SkillResponse> HandleRequest(SkillRequest input)
    {
        if(input.GetRequestType() == typeof(LaunchRequest))
        {
            return ResponseBuilder.Ask("Welcome to my skill written in one big function class with all my business logic in one place and no real testability! Ask me anything!", null);
        }

        if(input.GetRequestType() == typeof(IntentRequest))
        {
            var intentRequest = input.Request as IntentRequest;

            switch(intentRequest.Intent.Name)
            {
                case "MyIntent1":
                    // get slot values
                    // search database
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent2":
                    // get slot values
                    // search third party api
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent3":
                    // get slot values
                    // search database
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent4":
                    // get slot values
                    // search third party api
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent5":
                    // get slot values
                    // search database
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;

                // I think you get my point here...
            }
        }

        return ResponseBuilder.Tell("Something went wrong. Please try again later");
    }
}

So that’s pretty gross right? It’s untestable, difficult to update, and hard to read! But hey, we’re C# developers. So let’s build Alexa Skills like C# developers.

The proposal here is to abstract your intent logic into Handler classes. Then you can inject those either into your Function or your Controller if you’re using a RESTful API.

Here’s something that I hope can get you started:
– A generic IIntentHandler
– An inherited specific IIntentWhateverHandler
– An implementation of the IIntentWhateverHandler
– A testable and injectable version to be used in the function.

Let’s start.

IIntentHandler.cs

public interface IIntentHandler
{
    Task<SkillResponse> HandleIntent(IntentRequest input);
}

Now let’s get specific. In this simple case, this interface is empty but exists for registration – although you can add specific methods here as needed.

IMyIntentHandler.cs

public interface IMyIntentHandler : IIntentHandler
{
}

Now let’s create an example implementation of an intent handler that houses the business logic of the request.

MyIntentHandler.cs

public class MyIntentHandler : IMyIntentHandler
{
    private readonly MyDbContext _context;
    public MyIntentHandler(MyDbContext context)
    {
        // oh snap, we can inject db context
        _context = context;
    }

    public async Task<SkillResponse> HandleIntent(IntentRequest input)
    {
        var mySlot = input.Slots["MySlot"].Value; // assumes the slot is there from it being required in the interaction model
        var myMessage = await _context.Messages.FirstOrDefaultAsync(m => m.SomeValue == mySlot)

        if(myMessage == null)
        {
            return ResponseBuilder.Ask("I don't know that one. Try something else.");
        }

        return ResponseBuilder.Tell(myMessage.Content);
    }
}

Now let’s go about adding these handlers to our Function (the same thing can apply to our Controllers.

PrettyFunction.cs

public class Function
{
    private readonly IMyIntentHandler _myIntentHandler;

    private void Setup()
    {
        _myIntentHandler = new MyIntentHandler(...);
        // create the others - optionally implement a ServiceCollection
        // to handle proper dependency injection
    }
    public async Task<SkillResponse> HandleRequest(SkillRequest input)
    {
        if(input.GetRequestType() == typeof(LaunchRequest))
        {
            return ResponseBuilder.Ask("Welcome to my skill written in one big function class with all my business logic in one place and no real testability! Ask me anything!", null);
        }

        if(input.GetRequestType() == typeof(IntentRequest))
        {
            var intentRequest = input.Request as IntentRequest;

            switch(intentRequest.Intent.Name)
            {
                case "MyIntent1":
                    return await _myIntentHandler.HandleIntent(intentRequest);
                    break;
            }
        }

        return ResponseBuilder.Tell("Something went wrong. Please try again later");
    }
}

So now you can separately test your Handler classes, your Data classes, and your Function as a whole.

SO much better 🙂

Conclusion

We don’t have to follow how Amazon writes their node.js skills when we write them in C# – let’s use some proper OO design and testability to build some scalable and awesome skills!

In the next post, we’ll talk about taking this one step closer to avoid that gross switch statement and simply register our Handler implementations for certain intents or RequestTypes which is more similar to how the actual ASK SDK works.

Stay tuned!


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 Entity Framework in Your C# Alexa Skill Lambda

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 that developers might not be aware of, design patterns that and how they can be applied to voice application development, best practices, and more!

In the previous Alexa.Tip, we explored Accessing Lambda Environment Variables in .NET in order to access a secure connection string and initialize a DbContext to use.

If you don’t know how to access Lambda Environment variables already, PLEASE read that post first as this post’s samples will NOT show the use of hard coded connection strings – let’s follow some best practices! 😀

Alright, let’s get into it. If you’re developing Alexa Skills in .NET, you probably need to access data somewhere! At least if you’re building a real-world scale voice application. Also, if you’re a .NET developer, you’re probably used to accessing data through Entity Framework at this point rather than using some of the AWS SDKs and data services such as DynamoDB.

It’s super easy…

Initial Skill

First off, this example uses a super basic skill where the only custom intent is to get facts about animals. Here’s the intent setup in the UI:
AnimalFactIntent_Full

You can also find the interactionModel.json here:
https://github.com/SuavePirate/Cross-Platform-Voice-NET/blob/master/src/End/AnimalFacts/AnimalFacts/InteractionModels/alexaInteractionModel.json

Let’s start by abstracting some handlers out so we aren’t writing everything in our Function class – this isn’t JavaScript after all:

WelcomeHandler.cs

public class WelcomeHandler : IResponseHandler
{
    public SkillResponse GetResponse(SkillRequest input)
    {
        return ResponseBuilder.Ask("Welcome to the animal facts voice app! You can ask me about all kinds of animals - try saying, tell me about dogs.");
    }
}

AnimalFactHandler.cs

public class AnimalFactHandler : IAsyncResponseHandler
{
    public async Task<SkillResponse> GetResponse(SkillRequest input)
    {
        // TODO: Do something with data to get the fact.
    }    
}

Then we can setup our Function:

Function.cs

public class Function
{
    // using these interfaces can help us use something like Moq to unit test this bad boy.
    private readonly IResponseHandler _welcomeHandler;
    private readonly IAsyncResponseHandler _animalFactHandler;

    public Function() 
    {
        _welcomeHandler = new WelcomeHandler();
        _animalFactHandler = new AnimalFactHandler();
    }  

    public async Task<SkillResponse> FunctionHandler(SkillRequest input, ILambdaContext context)
    {
        var requestType = input.GetRequestType();

        if (requestType == typeof(IntentRequest))
        {
            if ((input.Request as IntentRequest).Intent.Name == "AnimalFactIntent")
            { 
                return await _animalFactHandler.GetResponse(input);
            }
        }
        else if (requestType == typeof(Alexa.NET.Request.Type.LaunchRequest))
        {
            return _welcomeHandler.GetResponse(input);
        }    

        return ResponseBuilder.Ask("I'm not sure I know how to do that. Try asking me for an animal fact!");
    }
}

So we have a basic setup, but we need to actually implement something in the AnimalFactHandler. In this case, we want to do a SQL search for a fact about the animal that was asked about!

SO let’s start wiring up Entity Framework to this skill:

Add Models and Context

Let’s create a model for our AnimalFact entity to represent our table:

AnimalFact.cs

public class AnimalFact
{
    public int Id { get; set; }
    public string AnimalName { get; set; }
    public string Fact { get; set; }
}

And now let’s create a DbContext implementation with our AnimalFact:

AnimalContext

public class AnimalContext : DbContext
{
    public DbSet<AnimalFact> AnimalFacts { get; set; }
    public AnimalContext(DbContextOptions options)
        : base(options)
    {

    }

    public AnimalContext()
    {

    }
}

NOTE: If you are NOT also using this AnimalContext in a web app that handles the migrations, you’ll need to add either a web app or a console project with .NET Core to handle the migrations since it needs to be an executable project type. The assumption here is that you already have a project running these migrations so you can actually add data to it, but if you are starting here, simply create a new .NET Core web app project or Console app, reference your DbContext from a shared library between the Labmda project and the app project, then run your migrations from the app project.

From here on out, we assume you have the db created from your context and some data in it.

Updating the Skill Lambda

Now that we have a DbContext, let’s add it to our Function and AnimalFactHandler in order to search for the fact!

Let’s go to the AnimalFactHandler and setup the class to take the AnimalContext in the constructor so we can easily unit test and then use the slot value from the request to query for the animal:

AnimalFactHandler.cs

public class AnimalFactHandler : IAsyncResponseHandler
{
    private readonly AnimalContext _context;
    public AnimalFactHandler(AnimalContext context)
    {
        _context = context;
    }

    public async Task<SkillResponse> GetResponse(SkillRequest input)
    {
        // get the animal name from the slot
        var intent = (input.Request as IntentRequest).Intent;
        var animal = intent.Slots["Animal"].Value;

        // query for the fact
        var animalFact = _context.AnimalFacts
                            .Where(a => a.AnimalName.ToLower() == animal.ToLower())
                            .FirstOrDefaultAsync();

        // we found the animal!
        if (animalFact != null)
        {
            return ResponseBuilder.Tell(animalFact.Fact);
        }

        // couldn't find the animal - return a decent response
        return ResponseBuilder.Ask("I don't know about that animal. Try asking me about a different one!");
    }    
}

Now that we have the updated handler, let’s update the entry point to initialize and pass in the AnimalContext.

Function.cs

public class Function
{
    // using these interfaces can help us use something like Moq to unit test this bad boy.
    private readonly IResponseHandler _welcomeHandler;
    private readonly IResponseHandler _animalFactHandler;
    private readonly AnimalContext _context;

    public Function() 
    {
        var connectionString = Environment.GetEnvironmentVariable("DatabaseConnectionString");
        var timeoutSetting = Environment.GetEnvironmentVariable("DatabaseCommandTimeout");
        var optionsBuilder = new DbOptionsBuilder<AnimalFactContext>()
            .UseSqlServer(connectionString, providerOptions => providerOptions.CommandTimeout(int.Parse(timeoutSetting)));
        _context = new AnimalFactContext(optionsBuilder.Build());
        _welcomeHandler = new WelcomeHandler();
        _animalFactHandler = new AnimalFactHandler(_context);
    }  

    public SkillResponse FunctionHandler(SkillRequest input, ILambdaContext context)
    {
        var requestType = input.GetRequestType();

        if (requestType == typeof(IntentRequest))
        {
            if ((input.Request as IntentRequest).Intent.Name == "AnimalFactIntent")
            { 
                return _animalFactHandler.GetResponse(input);
            }
        }
        else if (requestType == typeof(Alexa.NET.Request.Type.LaunchRequest))
        {
            return _welcomeHandler.GetResponse(input);
        }    

        return ResponseBuilder.Ask("I'm not sure I know how to do that. Try asking me for an animal fact!");
    }
}

Now we can publish this and check out our results!

Results

For example, I’ll use Swagger to create an animal fact, and then ask for it!

Boom – created:
create_dog_fact.PNG

And now let’s ask for it!

dog_fact_response

Conclusion

Adding data-driven responses to your custom Alexa Skills is dead easy using techniques you may already be familiar with if you are a .NET web developer! Show me what you’ve built with .NET and Alexa in the comments!


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/