autofac, dotnet, testing comments edit

Autofac DNX support is under way and as part of that we’re supporting both DNX and DNX Core platforms. As of DNX beta 6, you can sign DNX assemblies using your own strong name key.

To use your own key, you need to add it to the compilationOptions section of your project.json file:

{
  "compilationOptions": {
    "keyFile": "myApp.snk"
  }
}

Make sure not to specify keyFile and strongName at the same time - you can only have one or the other.

The challenge we ran into was with testing: We wanted to run our tests under both DNX and DNX Core to verify the adjustments we made to handle everything in a cross-platform fashion. Basically, we wanted this:

dnvm use 1.0.0-beta6 -r CLR
dnx test/Autofac.Test test
dnvm use 1.0.0-beta6 -r CoreCLR
dnx test/Autofac.Test test

Unfortunately, that yields an error:

System.IO.FileLoadException : Could not load file or assembly 'Autofac, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. General Exception (Exception from HRESULT: 0x80131500)
---- Microsoft.Framework.Runtime.Roslyn.RoslynCompilationException : warning DNX1001: Strong name generation is not supported on CoreCLR. Skipping strongname generation.
error CS7027: Error signing output with public key from file '../../Build/SharedKey.snk' -- Assembly signing not supported.
Stack Trace:
     at Autofac.Test.ContainerBuilderTests.SimpleReg()
  ----- Inner Stack Trace -----
     at Microsoft.Framework.Runtime.Roslyn.RoslynProjectReference.Load(IAssemblyLoadContext loadContext)
     at Microsoft.Framework.Runtime.Loader.ProjectAssemblyLoader.Load(AssemblyName assemblyName, IAssemblyLoadContext loadContext)
     at Microsoft.Framework.Runtime.Loader.ProjectAssemblyLoader.Load(AssemblyName assemblyName)
     at dnx.host.LoaderContainer.Load(AssemblyName assemblyName)
     at dnx.host.DefaultLoadContext.LoadAssembly(AssemblyName assemblyName)
     at Microsoft.Framework.Runtime.Loader.AssemblyLoaderCache.GetOrAdd(AssemblyName name, Func`2 factory)
     at Microsoft.Framework.Runtime.Loader.LoadContext.Load(AssemblyName assemblyName)
     at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(AssemblyName assemblyName)
     at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)

I ended up filing an issue about it to get some help figuring it out.

Under the covers, DNX rebuilds the assembly under test rather than using the already-built artifacts. This was entirely unclear to me since you don’t actually see any rebuild process happen. If you turn DNX tracing on (set DNX_TRACE=1) then you actually will see that Roslyn is recompiling.

If you want to test the same build output under different runtimes, you need to publish your tests as though they are applications. Which is to say, you need to use the dnu publish command on your unit test projects, like this:

dnu publish test\Your.Test --configuration Release --no-source --out C:\temp\Your.Test

When you run dnu publish you’ll get all of the build output copied to the specified output directory and you’ll get some small scripts corresponding to the commands in the project.json. For a unit test project, this means you’ll see test.cmd in the output folder. To execute the unit tests, you run test.cmd rather than dnx test\Your.Test test on your tests.

The Autofac tests now run (basically) like this:

dnvm use 1.0.0-beta6 -r CLR
dnu publish test\Autofac.Test --configuration Release --no-source --out .\artifacts\tests
.\artifacts\tests\test.cmd
dnvm use 1.0.0-beta6 -r CoreCLR
.\artifacts\tests\test.cmd

Publishing the unit tests bypasses the Roslyn recompile, letting you sign the assembly with your own key but testing under Core CLR.

I published an example project on GitHub showing this in action. In there you’ll see two build scripts - one that breaks because it doesn’t use dnu publish and one that works because it publishes the tests before executing.

autofac comments edit

Today we pushed the following packages with support for DNX beta 6:

This marks the first release of the Autofac.Configuration package for DNX and includes a lot of changes.

Previous Autofac.Configuration packages relied on web.config or app.config integration to support configuration. With DNX, the new configuration mechanism is through Microsoft.Framework.Configuration and external configuration that isn’t part of web.config or app.config.

While this makes for a cleaner configuration story with a lot of great flexibility, it means if you want to switch to the new Autofac.Configuration, you have some migration to perform.

There is a lot of documentation with examples on the Autofac doc site showing how new configuration works.

A nice benefit is you can now use JSON to configure Autofac, which can make things a bit easier to read. A simple configuration file might look like this:

{
    "defaultAssembly": "Autofac.Example.Calculator",
    "components": [
        {
            "type": "Autofac.Example.Calculator.Addition.Add, Autofac.Example.Calculator.Addition",
            "services": [
                {
                    "type": "Autofac.Example.Calculator.Api.IOperation"
                }
            ],
            "injectProperties": true
        },
        {
            "type": "Autofac.Example.Calculator.Division.Divide, Autofac.Example.Calculator.Division",
            "services": [
                {
                    "type": "Autofac.Example.Calculator.Api.IOperation"
                }
            ],
            "parameters": {
                "places": 4
            }
        }
    ]
}

If you want, you can still use XML, but it’s not the same as the old XML - you have to make it compatible with Microsoft.Framework.Configuration. Here’s the above JSON config converted to XML:

<?xml version="1.0" encoding="utf-8" ?>
<autofac defaultAssembly="Autofac.Example.Calculator">
    <components name="0">
        <type>Autofac.Example.Calculator.Addition.Add, Autofac.Example.Calculator.Addition</type>
        <services name="0" type="Autofac.Example.Calculator.Api.IOperation" />
        <injectProperties>true</injectProperties>
    </components>
    <components name="1">
        <type>Autofac.Example.Calculator.Division.Divide, Autofac.Example.Calculator.Division</type>
        <services name="0" type="Autofac.Example.Calculator.Api.IOperation" />
        <injectProperties>true</injectProperties>
        <parameters>
            <places>4</places>
        </parameters>
    </components>
</autofac>

When you want to register configuration, you do that by building up your configuration model first and then registering that with Autofac:

// Add the configuration to the ConfigurationBuilder.
var config = new ConfigurationBuilder();
config.AddJsonFile("autofac.json");

// Register the ConfigurationModule with Autofac.
var module = new ConfigurationModule(config.Build());
var builder = new ContainerBuilder();
builder.RegisterModule(module);

Again, check out the documentation for some additional detail including some of the differences and new things we’re supporting using this model.

Finally, big thanks to the Microsoft.Framework.Configuration team for working to get collection/array support into the configuration model.

javascript, home comments edit

I have, like, 1,000 of those little keyring cards for loyalty/rewards. You do, too. There are a ton of apps for your phone that manage them, and that’s cool.

Loyalty card phone apps never work for me.

For some reason, I seem to go to all the stores where they’ve not updated the scanners to be able to read barcodes off a phone screen. I’ve tried different phones and different apps, all to no avail.

You know what always works? The card in my wallet. Which means I’m stuck carrying around these 1,000 stupid cards.

There are sites, some of them connected to the phone apps, that will let you buy a combined physical card. But I’m cheap and need to update just frequently enough that it’s not worth paying the $5 each time. I used to use a free site called “JustOneClubCard” to create a combined loyalty card but that site has gone offline. I think it was purchased by one of the phone app manufacturers. ((Seriously.)

So…

Enter: LoyaltyCard

I wrote my own app: LoyaltyCard. You can go there right now and make your own combined loyalty card.

You can use the app to enter up to eight bar codes and then download the combined card as a PDF to print out. Make as many as you like.

And if you want to save your card? Just bookmark the page with the codes filled in. Done. Come back and edit anytime you like.

Go make a loyalty card.

Behind the Scenes

I made the app not only for this but as a way to play with some Javascript libraries. The whole app runs in the client with the exception of one tiny server-side piece that loads the high-resolution barcodes for the PDF.

You can check out the source over on GitHub.

vs comments edit

I installed Visual Studio 2015 today. I had the RC installed and updated to the the RTM.

One of the minor-yet-annoying things I found about the RTM version showed up when I pinned it to my taskbar next to VS2013:

Confusing icons on the taskbar

Sigh.

Luckily it’s an easy fix.

Windows 7 / Server 2008

First, unpin VS2015 from your taskbar. You’ll put it back after you’ve fixed the icon.

Open up your Start menu and right-click on the “Visual Studio 2015” shortcut in there. On the context menu, choose “Properties.” Click the “Change Icon” button.

Click the 'Change Icon' button

VS2015 actually comes with a few icons. They’re not all awesome, but they’re at least different than the VS2013 icon. I chose the one with the little arrow because it’s, you know, upgraded from VS2013.

Pick a better icon

Click OK enough times to close all the property dialogs. You’ll see the icon in the Start menu has changed. Now right-click that and pin it to the taskbar. Problem solved.

At least you can tell which is which now

Windows 8 / Server 2012

If you haven’t pinned VS2015 to your taskbar yet, do that now so you can get a shortcut.

Open up the taskbar icons folder. This is at C:\Users\yourusername\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar.

Copy the “Visual Studio 2015” shortcut out of that folder and onto your desktop.

Unpin VS2015 from your taskbar. The shortcut in that TaskBar folder will disappear.

Right-click on the “Visual Studio 2015” shortcut you copied to your desktop. On the context menu, choose “Properties.” Click the “Change Icon” button.

Click the 'Change Icon' button

VS2015 actually comes with a few icons. They’re not all awesome, but they’re at least different than the VS2013 icon. I chose the one with the little arrow because it’s, you know, upgraded from VS2013.

Pick a better icon

Click OK enough times to close all the property dialogs. You’ll see the icon on your desktop has changed.

Right-click on the icon on your desktop and pin that one to your taskbar. A new shortcut with the correct icon will be added to that TaskBar folder and will appear on the taskbar. You can now delete the one from your desktop.

At least you can tell which is which now

gaming, xbox comments edit

I tried playing a couple of Xbox 360 Kinect games with my four-year-old daughter, Phoenix. We had less than stellar results.

The first game was “Sesame Street TV.” Basically it’s interactive Sesame Street. We picked it up from the library to try it and I’m glad it was free.

Problem 1: She’s very small compared to me. If the Kinect sees me, it somehow stops seeing her. And vice versa - if it sees her, it stops detecting me. There seemed to be a sort of very small “magic area” in the room where it’d find both of us.

Problem 2: The interaction for that game isn’t constant. It’s more like: they sing a song, then you have a small bit of interaction, then they tell a story, then there’s a small bit of interaction. She’ll watch or she’ll interact, but she loses interest in interacting once you switch to watching.

Problem 3: Slight misrepresentation of the game on the box. The concept behind the game is like you going into the TV and being on Sesame Street. There is a picture on the box to illustrate the concept. Phoenix wants that to be the reality. It is really hard to explain that the box just shows an idea of what it’s like, that you don’t really transfer yourself into the television.

After a bit of Sesame Street, we tried “Kinect Adventures.” I did this thinking that the constant interaction would keep her engaged.

We still ran into the problem where there was basically the small area where it recognized us both, but then it was compounded with a couple of new problems.

Problem 4: Many of the games aren’t obvious to four-year-olds. In particular, the game where you have to walk from side to side and jump to control the raft - that was entirely unintuitive to Phoenix. She was far more concerned with whether or not the avatar on the raft actually looked like her, which then led to a half-hour diversion where we had to set up an avatar.

Problem 5: Auto jump-in/jump-out. The ability to jump in and out of the game quickly is great for folks that “get it” and when you have a properly sized room without the “magic area” where you’re recognized. However, every time Phoenix accidentally stepped out of the “magic area,” her avatar would disappear because it thought she was jumping out of the game, at which point I’d have to try to convince her to come back into the area - but not too close to me - so we could continue.

In the end, we decided it a better idea to just go watch some Looney Tunes cartoons we picked up at the library. Which, now that I think about it, is sort of the opposite of what Kinect is trying to get you to do - get off the couch and be active. Hmmm.