Play by Play with Jon Skeet and Rob Conery

Tuesday, March 22, 2016 by K. Scott Allen

It started, as most endeavors involving Rob do, with a simple email that ends with “I think it will be fun!”.

Fast forward a bit and I’m in the ExCel London being mic’d up by a film crew. Jon is in the room wearing a t-shirt and the mic keeps falling off. Mine keeps folding under my collar, so I’m buttoned up to the top as if I were ready for morning mass. There’s an AV guy in front of us with safecracker headphones trying to eliminate all the hissing and crackling that comes to life in a room full of electrically powered machinery. We’re swapping microphones, changing cables, and positioning laptops. Just as we think we are ready to go – blam! My microphone belt pack falls off my chair. The lapel mic is ripped off my shirt and is tumbling arse over elbow across the floor. Safecracker guy is grimacing and muttering something in polite British. We’ve been at this setup for 30 minutes now and I’m starting to think the show will not go on.

We get setup again, and the recording begins. For the next 75 minutes we are knee deep in C# code, disassemblies, and expression trees. You can watch those 75 minutes in the Pluralsight Play by Play: C# Q & A.

Rob’s always right. It was fun.

 

Pluralight Play by Play: C# Q & A

Reusing JavaScript Template Literals

Monday, March 21, 2016 by K. Scott Allen

Stencil_Template_Ruler_

The word template in web programming makes one think of a reusable document or string you can combine with model data to produce output. Famous examples include Razor, Jade, and Handlebars. Template literals in JavaScript are not templates in this same sense, which is perhaps why they were originally referred to as quasi-literals in early specification work.

I've seen a number of developers become angry when thinking they can declare a template literal and then reuse the template with different inputs. Note: the following code doesn't work, but represents how one might think template literals should work.

let template = `${x} + ${y} = ${x+y}`;

let three = template.format({x:2, y:3});
let ten = template.format({x:5, y:5});

The runtime will evaluate the expressions inside the template immediately.  If x and y aren't available when the template is defined, a ReferenceError brings the script to a halt.

The easy solution, like most solutions in JavaScript, is to use a wrapper function.

let template = (x,y) => `${x} + ${y} = ${x+y}`;

let four = template(2,2);
let eight = template(6,2);

If you'd rather think in terms of model objects instead of individual parameters, add some destructuring to the parameter list.

let template = ({x,y}) => `${x} + ${y} = ${x+y}`;

let seven = template({x:4, y:3});
let three = template({x:1, y:2});

Binding Aurelia Routing Rules

Monday, February 22, 2016 by K. Scott Allen

Aurelia continues a march towards beta 2 with a big February release.  There are no breaking changes, and the framework still provides features to make building applications easy. One feature I’ve used recently is the navigation model provided by the Aurelia router. I think of the navigation model as an amalgamation of routing configuration with current routing state to provide a data source for navigation menus and other UI components.

The routing configuration comes from the conventional configureRouter method of a view model. For top-level routing, the method might look like the following.

configureRouter(config, router) {
    this.router = router; 

    config.title = "Movies";
    config.map([
        { route: "", name: 'home', moduleId: "movies/list", 
          title:"List", nav:true, settings: { icon: "home" }                
        },
        { route: "about", moduleId: "about/about", title: "About", nav:true },
        { route: "details/:id", name:"details", moduleId: "movies/details" },
        { route: "edit/:id", name:"edit", moduleId: "movies/edit" },
        { route: "create", name:"create", moduleId:"movies/edit" }
    ]);
}

Notice the nav and settings properties in the first RouteConfig entry. The nav property identifies to the router which of the entries are part of the navigation model. The settings property allows us to attach arbitrary data to a RouteConfig entry, data we might find useful when binding to the navigational model in a view. In this example, the setting is the name of a Font Awesome icon. We can use the resulting navigation model in a view like so:

<ul class="nav navbar-nav">
    <li repeat.for="row of router.navigation"
        class="${row.isActive ? 'active' : ''}">
        <a href.bind="row.href">
            ${row.title}
            <i if.bind="row.settings.icon" class="fa fa-${row.settings.icon}"></i>
        </a>
    </li>
</ul>

The navigation model is just one of many features to like about Aurelia.

Avoiding the Service Locator Pattern in ASP.NET Core

Thursday, February 18, 2016 by K. Scott Allen

Six years ago, Mark Seeman authored a post titled “Service Locator is an Anti-Pattern”. All of the problems Mark demonstrated back then are still problems today. I’ve been pointing developers to Mark’s post because the service locator anti-pattern is a pattern I’ve seen creep into some early ASP.NET Core code bases. The code usually looks something like the following:

var provider = HttpContext.ApplicationServices;
var someService = provider.GetService(typeof(ISomeService));

It is easy to use the service locator pattern in ASP.NET. Nearly every type of component, from controllers to views, have access to the new HttpContext, and HttpContext exposes a service provider via ApplicationServices and ReqeustServices properties. Even though HttpContext facilitates the service locator pattern, I try to avoid using these properties. 

The service locator pattern typically appears in applications that have not fully embraced an inversion of control container, or dependency injection. Yet, the new ASP.NET offers these features from the very beginning of an application, meaning it is just as easy (or easier) to avoid the service locator pattern.

For Startup

In “How To Stop Worrying About ASP.NET Startup Conventions”, I remarked how the Configure method of the Startup class for an application is an injectable method. The runtime will resolve any services you need from the application container and pass them along as arguments to this method.

public class Startup
{
    public void ConfigureServices(IServiceCollection services) { }
 
    public void Configure(IApplicationBuilder app,
                          IAmACustomService customService)
    {
        // ....   
    }        
}

For Middleware

Custom middleware has two opportunities to ask for services. Both the constructor and the conventional Invoke method are injectable.

public class TestMiddleware
{
    public TestMiddleware(RequestDelegate next, IAmACustomService service)
    {
        // ...
    }

    public async Task Invoke(HttpContext context, IAmACustomService service)
    {
        // ...
    }    
}

Constructor injection is good for those services you can keep around for the duration of the application, while Invoke injection is useful when you may need the framework to give you a service instance scoped to the current HTTP request.

For Controllers

Constructors are injectable.

public class HelloController : Controller
{
    private readonly IAmACustomService _customService;

    public HelloController(IAmACustomService customService)
    {
        _customService = customService;
    }

    public IActionResult Get()
    {
        // ...
    }
}

For Actions

You can also ask for a dependency in a controller action using the [FromServices] attribute on a parameter. Instead of model binding the parameter from the HTTP request environment, the framework will use the container to resolve the parameter. 

[HttpGet("[action]")]
public IActionResult Index([FromServices] IAmACustomService service)
{            
    // ...
}

For Models

[FromServices] also works on model properties. For example, the following action needs an instance of a TestModel.

public IActionResult Index(TestModel model)
{
    // ...
}

The TestModel class class looks like the following.

public class TestModel
{       
    public string Name { get; set; }

    [FromServices]
    public IAmACustomService CustomService { get; set; }
}

For property injection to work, the property does need a public setter. Also, constructor injection does not work for model objects. Both of these facts are lamentable.

For Views

In “Extending Razor Views”, I made the argument that the @inject directive should be the only extensibility mechanism you should use.

@inject IAmACustomService CustomService;
 
<div>
    Blarg   
</div>

For Everything Else, Even Filters

For every other type of component there is almost always a way to have constructor injection work. This is true even for action filters, which have been notoriously difficult in previous versions of ASP.NET MVC. For more on DI with filters specifically, see Filip’s post “Action Filters, Service Filters, and Type Filters”.

Back In Time with Windows IoT

Tuesday, February 16, 2016 by K. Scott Allen

After graduate school my first job was programming in assembly language for an 8 bit Hitachi CPU. The software would fire infrared light through organic substances to measure the amount of moisture or protein inside. Even at the low level of opcodes and operands, software (and hardware) still presented auras of mystery for me at this early point in my career. Every day presented a challenge and the opportunity for a thrill when bits aligned well enough to work.

I’ve largely ignored the Raspberry Pi since it first appeared. I bought one 2 years ago to give my youngest son some inspiration to write Python code. The plan worked. But, I’ve never bought one for myself, and assumed a “been there, done that” attitude.

Then one weekend, on a whim, I threw a CanaKit Raspbery Pi 2 kit into my shopping cart. Even though I had been there and I had done that, it was a long time ago. And, those being good times, maybe I could relive them a bit.

Running with Windows IoT

Growing up in a county with blue laws, I’m still astonished when a package arrives on a Sunday. Who needs delivery drones when sentient employees of the US Postal Service deliver packages with a smile?

Thanks to the Windows IoT Dashboard, I had the Pi booted into Windows 10 only 20 minutes after receiving the package.

 

Windows 10 IoT Dashboard 

The decision to use Windows 10 was an impulse decision. In hindsight, perhaps not the best decision for what I wanted to do with the Pi. Linux distros on the Pi give a general purpose operating system with the option to apt-get nearly any application, driver, or toolset. Win10 feels like an operating system built for a specific purpose – running Windows Universal application prototypes deployed by Visual Studio. Don’t think of Win10 IoT as Windows on an ARM processor. Win10 IoT has no Cortana, or start menu, or even a shell, for that matter. Although, it does listen for ssh connections out of the box.

SSH to Rasberry Pi2 with Win10 IoT

Win10 IoT has limited hardware support and does not support the WiFi dongle provided with the CanaKit I bought. I had to plug in an Ethernet cable before I was able to reach the Pi with ssh. Win10 does support a $10 Realtek dongle, which I purchased days later and works well. If I knew before what I know now, I would have checked the hardware compatibility list up front, but my impulse buys rarely exhibit such caution. 

You can also connect to Win10’s built-in web site on port 8080. This is the easiest way to configure devices like the WiFi dongle, although you can also run netsh commands through ssh or remote Powershell.

 

Windows 10 Iot Config

 

Running .NET Core

Although running a Windows Universal app was tempting, I wanted to use .NET Core (currently dnx) to get some bits working on the Pi. The setup is remarkably easy. The first step is getting some Core CLR bits onto the development machine.

dnvm install latest -r coreclr -arch ARM -u

The key options here is –arch ARM. Note there is currently an issue here, as dnvm will use the new install to set the process path. Since the path is for an ARM architecture, dnx is unusable until you dnx use a runtime with the appropriate architecture. Then, once you have an application written, be it command like or web application, use dnu (currently) to publish the application, including the runtime.

dnu publish --out "c:\out\HelloPi2" --runtime dnx-coreclr-win-arm.1.0.0-rc2-16357

The above command packages the application, including source and the full runtime framework. There output folder will contain ~45MB of files, which is why the --native switch will be useful in the future when it works properly. Deployment is a simple xcopy to the Pi file share, and execution only requires finding and running the .cmd file dnu creates in the approot folder.

In Conclusion

Working with Windows IoT and the Pi is not quite what I remember from the old days of EEPROM burners and oscilloscopes. It’s too easy. But, there still is some magic in fiddling with a relatively raw piece of hardware. 

How To Stop Worrying About ASP.NET Startup Conventions

Tuesday, February 9, 2016 by K. Scott Allen

There are 2 kinds of developers. Those who love conventions and those who loathe conventions. The former group sees conventions as a means to remove boilerplate code and expose the essence of software by avoiding ceremony. The later group tends to view conventions as dangerous magic. It’s also the later group, I’ve found, which tends to dislike the Startup class in ASP.NET Core applications.

public class Startup
{
    public void ConfigureServices() { }
    public void Configure() { }
}

Questions around Startup generally revolve around the following themes:

1. Why isn’t there a required interface available for Startup to implement?

2. How do I know what methods are needed and what parameters the methods will accept?

The short answer to both of these questions is that conventions offer more flexibility than contracts.

Naming Conventions

Programming against conventions is frustrating when you don’t know the conventions. The software won’t behave correctly, and in many convention oriented systems you won’t see any error message or know how to start debugging. Conventions are indistinguishable from magic.

Fortunately, for the startup scenario, the runtime does give you some actionable error messages when you miss a convention. For example, if you don’t have a proper class name for the startup code, ASP.NET will give you the following.

A type named Startup could not be found

Here, the runtime will not only tell you what is missing, but also give you hints where you can find some wiggle room. You can have a dedicated startup class for any given environment, and use Startup itself as a default fall back. StartupDevelopment, StartupProduction, and StartupYourEnvironmentNameHere can all live in the same project and provide the startup configuration for their given environment name.

The same convention also applies to the Configure method in a startup class. In other words, once the runtime locates the startup class for the application, it will look for Configure and ConfigureServices methods that optionally have the environment name as a suffix.

A public method named Configure could not be found

One difference between Configure and ConfigureServices is that ConfigureServices is entirely optional. If you don’t provide the method, the runtime will carry on with only default services installed.

These types of conventions are impossible to enforce using interfaces. Attributes could make the purpose of a class more explicit, but attributes would add ceremony with little benefit.

Versus Interfaces

Another difference between the Configure and ConfigureServices methods is how the ConfigureServices method can only take a parameter of type IServiceCollection. The Configure method, on the other hand, is an injectable method. You can take any number and types of parameters in Configure as long as the underlying IoC container can locate a service to populate the parameter.

public class Startup
{
    public void ConfigureServices(IServiceCollection services) { }

    public void Configure(IApplicationBuilder app,
                          IApplicationLifetime lifetime,
                          IHostingEnvironment hostingEnvironment,
                          IApplicationEnvironment applicationEnvironment)
    {
        // ....   
    }        
}

The type of flexibility demonstrated by Configure is impossible to describe using a C# interface, and it is not the sort of flexibility you want to lose just to have a simplistic compile time check, at least not when the error messages are so explicitly good. Don’t worry about the conventions, the runtime will let you know when you goof.

The New Fetch Standard

Monday, February 8, 2016 by K. Scott Allen

The XMLHttpRequest object has been around, in one form or another, since 1999. XHR has been a key ingredient in most web applications for well over a decade now. During that time various libraries have wrapped the API to make XHR more palatable and easier to use, while vendors have extended the capabilities of XHR to support binary data, cross origin requests, and progress events. It’s been quite the ride, but the future is fetch.

Think of fetch as a modernized XMLHttpRequest. The raw API is easier to use, and all starts with a global fetch method.

var movie = {
    id: 1,
    title: "Star Wars"
};

fetch("/movies", {
    method: "put",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify(movie)
}).then(function(response) {
    return response.text()
}).then(function(result) {
     console.log(result);
});
    

With promises now an official part of the JavaScript language, it is nice to see standard APIs using promises instead of callbacks.

Browser support for fetch is coming along (I ran the above sample in Chrome 47), although the API is still a work in progress. The API allows us to influence the caching mode directly ({cache:”reload”}, as one example), which is good, but timeouts and deadlines are still open issues and not yet in the spec.

Pluralsight Courses
What JavaScript Developers Should Know About ECMAScript 2015
The Podcast!