Monthly Archives: September 2018

Microsoft Chat Bot Framework – Up And Running

Some time ago (think early to mid-nineties), I used to run a BBS. One Christmas, I logged onto another BBS based in Manchester, and they had a “Santa Chat”. I tried it for a while, and was so impressed by it, that I decided to write my own; it was basically the gift that kept giving: you put this thing on your BBS (basically an Eliza clone) and it records the responses of the unsuspecting users to a text file (or log).

These days there are laws against recording such things, but those were simpler times, and once they realised the joke, everyone was happy, and life went on (albeit at 14.4k bps).

A few years ago, I decided to relive my youth, and wrote an app for the Windows Store – this one didn’t keep logs, although I imagine, had I added a “Post Log to Facebook” button, it probably would have got some use. It has since removed by MS in their wisdom. There was very little difference between it and Eliza.

Now, Microsoft seem to have jumped on this bandwagon, and they have released a framework for developing such apps. Clearly their efforts were just a copy of mine… well, anyway, this is a quick foray into the world of a chat bot.

You’re first step, in Azure, is to set-up a Web-App bot:

This will actually create a fully working bot in two or three clicks; select “Test in Web Chat” if you don’t believe me:

Okay – it doesn’t do much – but what it does do is fully working! You can download the code for this if you like:

The code doesn’t look too daunting when you download it:

In fact, looking inside MessagesController, it appears to be a simple API controller. In fact, the controller selects a dialog to use, and the dialog is the magic class that essentially controls all the… err… dialog. The default is called “EchoDialog”.

For the purposes of this demo, we can change the part we want using the web browser; select Online Code Editor:

The bit we’re interested in for the purpose of this is the EchoDialog. Let’s try changing the text that gets sent back a little; replace the test in MessageReceivedAsync with this:

public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
    var message = await argument;
 
    if (message.Text == "reset")
    {
        PromptDialog.Confirm(
            context,
            AfterResetAsync,
            "Are you sure you want to reset the count?",
            "Didn't get that!",
            promptStyle: PromptStyle.Auto);
    }
    else
    {
        if (message == "test")
        {
            await context.PostAsync("Testing 1, 2, 3...");
        }
        else
        {
            await context.PostAsync($"{this.count++}: You said {message.Text}");
        }
        context.Wait(MessageReceivedAsync);
    }
}

So, we are checking the input, and where it’s “test”, we’ll return a slightly different response. You’ll need to build this; select the “Open Console” button down the left hand side of the screen and type “build”:

When it’s done, open up your test again and see what happens:

Remember that the bot itself is exposed as an API, so you can put this directly into your own code.

References

https://blogs.msdn.microsoft.com/uk_faculty_connection/2017/09/08/how-to-build-a-chat-bot-using-azure-bot-service-and-train-it-with-luis/

https://github.com/Microsoft/BotFramework-Emulator

Set-up a new Asp.Net Core 2.1 Project with Docker

Until recently, I’ve pretty much managed to avoid the container revolution. However, as the tools are becoming much more integrated, and the technology much more pervasive, I thought I’d document my journey into the world of containers.

As far as I can tell, the battle between types of containers and orchestrators is now over, and the VHS has emerged as Docker and Kubernetes; at least, MS, Google and Amazon seem to think so.

Docker – from step 0

Let’s follow the process through from nothing; the first step is to visit the Docker Store here.

Once you’re there, you’ll need to pick a username and sign in. After this, you can download Docker for Windows:

Once downloaded, run it, and you’ll see this bizarre screen, that seemingly lives in your way:

You can just close this: docker actually lives in your system tray. Right click there and select Settings:

Share your drive that you’re planning to run your Asp.Net Core code from.

By default, docker installs with a Linux bias, so the next step is to switch to Windows Containers (again in the right-click context menu):

Finally, some code…

Okay, Docker is now primed and ready to run a container. Let’s create our new project:

After you okay this, you’ll notice that there’s a new “Add Docker Support” in the create Project dialogue:

Once you create this (and persuade your browser and Docker that you’re not too bothered about certificates for the minute) it should run out of the box:

To prove it’s running, open Power Shell and type:

 docker ps

Or, to take the more brute force approach by just restarting docker and have a look at VS:

References

https://stackify.com/azure-container-instances/

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/visual-studio-tools-for-docker?view=aspnetcore-2.1

Unit Testing With Entity Framework and Entity Framework Core 2.1

Entity Framework Core 2.1 comes with a nifty little feature: an In Memory Database setting. What this means, is that with a single option setting, your tests can interact directly with the database (or at least EF’s impression of the database) but not actually touch any physical database. In other words, you can write unit tests for data access; an example:

// Arrange
DbContextOptions<ApplicationDbContext> options = new DbContextOptionsBuilder<ApplicationDbContext>()
    .UseInMemoryDatabase(Guid.NewGuid().ToString())
    .EnableSensitiveDataLogging()                
    .Options;

using (var context = new ApplicationDbContext(options))
{
    context.Database.EnsureDeleted();
	ResourceCategory resourceCategory = new ResourceCategory()
    {
        Name = "TestCategory"
    }
};
 
// Act
_applicationDbContext.ResourceCategories.Add(resourceCategory);
_applicationDbContext.SaveChanges();
	
 
// Assert                
Assert.Equal("TestCategory", context.ResourceCategories.First().Name);               

To just quickly explain what this is doing: we have a DbContext called ApplicationDbContext and we’re building a set of options on top of that context. We’re then instantiating the context and cleaning the in memory database. Finally, we’re adding a new piece of data to the context and then asserting that it has been added.

Told you it was nifty.

But what about if you’re still using Entity Framework 6?

Glad you asked.

Out of the box, EF does not come with this kind of functionality; however, I recently came across (and contributed) to a NuGet library that provides just such a facility. It provides a wrapper for both Moq and Nsubstitute. The GitHub Repo is here.

ReadOnly Entity Framework

Ever come across a situation where you want to use an Entity Framework data layer in a little tool or report, but ended up reverting to Ado.Net or a different ORM because EF is a little bit like a Heisenberg Framework (it changes things that it looks at)? You might have a seed method that tries to update data, or a migration that you don’t want to apply.

Apologies in advance if this seems like stating the bloody obvious; but it didn’t seem obvious to me at the time. If there’s a neater way to do this then please let me know.

Anyway, I recently had this issue, and came up with the idea of a ReadOnly DBContext. For example, your main DBContext might look like this:

    public class MyDbContext : DbContext, IMyDbContext
    {
        static MyDbContext()
        {            
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
        }
 
        public MyDbContext()
            : base("connection-string")
        {
            
            
        }
 
        public MyDbContext(string connectionString)
            : base(connectionString)
        {
 
 
        }
 
        public DbSet<Entity1> Entity1 { get; set; }
        public DbSet<Entity2> Entity2 { get; set; }
 
        void IMyDbContext.SaveChanges()
        {
            base.SaveChanges();
        }
 
        Task IMyDbContext.SaveChangesAsync()
        {
            return base.SaveChangesAsync();
        }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Entity1>()
                .HasOptional(a => a.Field2)
                .WithMany();            
  
            base.OnModelCreating(modelBuilder);
        }
    }

Making a ReadOnly version of this is pretty much removing the code; for example:

    public class MyReadOnlyDbContext : DbContext, IMyDbContext
    {
        static MyReadOnlyDbContext()
        {            
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyReadOnlyDbContext, Configuration>());
        }
 
        public MyReadOnlyDbContext()
            : base("connection-string")
        {
            
            
        }
 
        public MyReadOnlyDbContext(string connectionString)
            : base(connectionString)
        {
 
 
        }
 
        public DbSet<Entity1> Entity1 { get; set; }
        public DbSet<Entity2> Entity2 { get; set; }
 
        void IMyDbContext.SaveChanges()
        {

        }
 
        Task IMyDbContext.SaveChangesAsync()
        {
		  return Task.CompletedTask;

        }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Entity1>()
                .HasOptional(a => a.Field2)
                .WithMany();
  
            base.OnModelCreating(modelBuilder);
        }
    }

An easy way to return the read only version, rather than the main version is via a DbContextGenerator:

public class DbContextGenerator : IDbContextGenerator
{
    private readonly AppSettings appSettings;        
 
    public DbContextGenerator(AppSettings appSettings)
    {
        this.appSettings = appSettings;            
    }
 
    public IMyDbContext GenerateDbContext()
    {            
        if (appSettings.ReadOnly)
        {
            return new MyDbReadOnlyContext(appSettings.DatabaseConnectionString);
        }
        return new MyDbContext(appSettings.DatabaseConnectionString);                        
    }
}

This can be registered in the IoC and will return a DB Context based on a read only flag.

It’s worth noting that if your model doesn’t match, it will likely crash. It’s also worth noting that if you’re reading this article and trying to work out how you can use EF without having it manage the DB then it’s probably because something, somewhere, went wrong: this isn’t a suggestion for a new way to use EF, it’s a way to use EF in a temporary fashion.