Skip to content
May 16 / davidalpert

Chocolatey – The remote server returned an error: (404) Not Found

Recently I’ve run into the following error while installing a chocolatey package:

When I went a-googling, this was the closest thing that I found:

Which suggested the following steps:

  1. update your Chocolatey version;
  2. run ‘choco sources’ and ensure that the sources make sense.

When I followed these steps I saw that Chocolatey was configured to use the following sources:

  • [local nuget server]
  • [local chocolatey server]
  • https://chocolatey.org/api/v2/

Pinging each of these returned a quick result for the two internal servers, and timeouts for chocolatey.org, however I could load up chocolatey.org through a web browser without issue.

Quick detour: debug output

Running Chocolatey with a -d flag shows debugging output.

So what gives?

Not sure, but here is what worked:

Feb 18 / davidalpert

Sam CPU Won’t Sleep

I recently received the gift of a new laptop at the office and let’s face it, what geek doesn’t love new hardware?

While setting up this Windows 7 machine I ran into a small snag; it wouldn’t hibernate or go to sleep. I have to say that the stability improvements to hibernate and sleep that were introduced with Windows 7 have meant that I hardly ever reboot my laptop and rarely run into problems. So although this refusal to stay down did bring up memories of one of my favorite children’s books, you can imagine that it was frustrating to ask the system to go to sleep only to have it wake itself up again seconds later.

Fortunately, even on Windows…

There’s an app for that!

A quick search turned up the powercfg utility which was just what I needed.

Running “powercfg -devicequery wake_armed” from a command prompt will list the devices that are authorized (i.e. “currently configured”) to wake your machine. This puts you in the position to call “powercfg -devicedisablewake devicename” where you can substitute for devicename an entire line copied from the results of your devicequery. Here is the content from my shell session:

After doing this for each of the devices returned from my query, I put the machine to sleep and it stayed that way – that makes powercfg my new fat cat.

Even better, this is just scratching the surface of what powercfg can do. If you’re a geek running Windows and haven’t explored the low-level system tweaking supported by this tool, go try it.

And sleep well.

Feb 6 / davidalpert

How to restore all nuget packages for a solution using MSBuild

I was pairing on some code this afternoon and ran into a problem; while our .NET solution would “worked on our machine“™ but would fail on the build server with a message about missing references.

It turns out that ReSharper, which is used heavily on our team, offers a quick-fix option on a recognized but not imported type to “reference ‘{missing assembly}’ and use ‘{fully qualified name of type}’” and team members would sometimes use this quick-fix to add references instead of nuget. When the given .dll was found in a packages folder, the reference added to the project would be into the given package folder. Before version 8.0, however, ReSharper would add the assembly reference but not update the project’s packages.config file.

This would often go unnoticed on a local machine as the bits already existed in the packages folder, but when a build server checks out the code fresh or you happen to do a full clean that includes removing the packages folder, you may run into a race condition where the project without the reference in packages.config gets built before any project with a reference in packages.config. In that case, MSBuild cannot find the referenced package and the compile fails.

This is what was happening on our build server.

My pairing partner suggested that we write a quick build script to download all the packages before building the solution, which was much simpler than my previous approach of scanning the projects to look for missing references.

As suggested, then, here is an msbuild script that loops through all the packages.config files in your solution folder and restores all missing packages.

Include this target as a pre-build step and the symptom will disappear.

A simpler approach

Of course, now that I’ve finished a bit of internet digging reveals why you should always research existing solutions before building your own.

It turns out that a set of improvements were released in NuGet 2.7 that simplify this further.

Now restoring all nuget packages for a solution from the command-line is a simple one-liner:

  • nuget.exe restore path\to\solution.sln

And wrapping that in MSBuild is only a few more lines.

That’s much cleaner than my original implementation, but I’ve included it here for reference as it demonstrates batching and how you might exercise more explicit control over which packages get restored by a given build step.

Just patch ReSharper (a.k.a. the JetBrains folks rock!)

Finally, because this was a well known issue with ReSharper since early 2012, not only did the folks at JetBrains release a plugin for version 6 and 7 of ReSharper in late 2012 that used nuget to add the reference, but apparently they also fixed this issue in version 8.

Jan 3 / davidalpert

Chocolatey: The ‘minClientVersion’ attribute is not declared

I love Chocolatey. As many have said “it’s like apt-get for windows” and for the most part it just works. Kudos to Rob Reynolds for putting it together.

Get your minClientVersion attribute on

This week while working on a side project I ran into a known issue with the newly added ‘minClientVersion’ attributes in nuspec files.

A quick google on the error message turned up this post to the chocolatey google group, but after clearing my nuget cache the problem persisted so I turned to investigate the version of nuget.exe.

When I ran ‘nuget pack’ in my project folder it completed no trouble.

Running ‘nuget’ alone showed me I was using version 2.7.41115.310 which at the time is tagged as version 2.7.3 and is the most up-to-date release available. So clearly the nuget client on my machine was able to package up my project.

Still, when I ran ‘cpack’ which aliases to ‘chocolatey pack’ it failed with the error above: “The ‘minClientVersion’ attribute is not declared.

Which nuget client was that?

It turns out that the Chocolatey-Pack command (and probably several other chocolatey nuggets of goodness) use their own copy of nuget.exe located at the path included in the output above.

Running ‘c:\chocolatey\chocolateyInstall\nuget.exe’ showed me that nuget client was at version 2.1.31022.9038.

Aha!

Update your chocolatey nuget client

Running ‘c:\chocolatey\chocolateyInstall\nuget.exe update -self’ updated that chocolatey nuget client.

Nice package!

And finally, running ‘cpack’ in my project folder now completed without a hitch.

Long story short, you can have many versions of nuget.exe on your machine so if nuget starts behaving funny it’s important to know which nuget client is throwing the error!

Oct 17 / davidalpert

Resharper: Test wasn’t run

I just noticed that a set of tests in my current project were showing as inconclusive in the Resharper test runner in Visual Studio 2012. Clicking on an individual test showed only the message “Test wasn’t run” with no obvious output in the test runner or the output tab.

Turns out the problem was in the test project’s app.config file.

I had a binding redirect that was pointing to a version of an assembly that I wasn’t deploying with the test project.

In short, any problem loading your test assembly may generate the same behavior in either the Visual Studio or Resharper test runners.

If you run into a “Tests weren’t run” error in Visual Studio, review your app.config file for syntax errors and binding redirects that might be broken.

Jun 2 / davidalpert

On estimates and budgets in software

Towards the end of a planning meeting at the office last week, a colleague lamented the fact that developers are reluctant to give estimates. He went on to express frustration that speaking in terms of budgets seems to go more easily when, in fact, a budget is the same thing as an estimate. I tried to explain the difference between estimates and budgets and why that difference matters to developers.

It’s true that budgets and estimates can play similar roles in the context of planning; both provide a means to tell a story about the future (i.e. make a plan) upon which consensus can be built and other, downstream decisions can be made.

This act of planning forward and coordinating the conversion of various benefits into profitable activity is core to any business beyond a certain size or level of maturity, and the basic questions of planning are really quite reasonable:

  • What am I going to get?
  • When will I get it?
  • How much will it cost me?

The core difference between estimates and budgets that is relevant to developers, however, is that estimates are something that we give to the business while budgets are something that we receive from the business.

This may appear like a subtle distinction that is pure semantics, but think about it from our point of view.

The act of giving an estimate exposes us, makes us vulnerable. We might be wrong, and frequently are. An estimate is, after all, only a guess. An educated guess, we hope, but still, only a guess. We are often asked to give estimates on problems or solutions that we don’t fully understand. We are often asked to give estimates without understanding the business context in which those estimates will be evaluated, or without any idea of what the customer things is reasonable.

Receiving a budget, however, is much more comfortable; it clarifies what the business expects of the development team and is basically a goal with a set of constraints.

We developers, problem-solvers by nature, practice, and training that we are, love nothing more than to figure out how to achieve a goal within (and despite) a set of constraints.

That’s what we do.

Give us a goal and some constraints and our brains immediately start thinking through possible solutions, exploring different possibilities, sifting out the promising from the futile, and generally solving the problem.

I like to look at estimates and budgets as two sides of an ongoing conversation between a delivery team (of software developers) and a business/management team (e.g. a project manager or department head):

A business manager asks a developer for an estimate;

The developer team responds with an estimate (or several) and some conditions;

The business manager integrates those estimates with their broader knowledge of business or market goals and creates a budget;

The development team offers up more information and some other options;

The buisness manager updates and confirms the budget;

The development team works to deliver within that budget.

Notice the back-and-forth nature of this conversation.

Notice how the estimates are context that the development team provides to the business, but the business still takes responsibilty for planning.

Postscript

After spinning out this line of thought, what I’d really like to leave you with is the observation that all of this appears to matter much less in environments with a high degree of trust.

May 18 / davidalpert

More Sprache goodness

Following my experiment to write a parser for Visual Studio solution files using the Sprache library, I’d like to share a few Sprache techniques that I found useful.

Parse a token into an enum value

The Visual Studio solution file format includes a set of Project definitions, each with one or more ProjectSection definitions, as well as a collection of GlobalSection definitions.

    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection

Each ProjectSection and GlobalSection contains a token (preSolution in this case) that instructs Visual Studio when it’s contents are required during the process of opening a solution file:

To represent this in my data model I created the following enum to express these loading sequence tokens:

    public enum SectionLoadSequence
    {
        Unrecognized,
        PreSolution,
        PostSolution,
        PreProject,
        PostProject
    }

The Pre- and Post- nodes should be self-explanitory, but I want to temporarily call attention to the Unrecognized value.

I have found it useful to introduce in my grammars the concept of an unrecognized section which, while it may not survive into the final draft of a particular grammer, has allowed my parsers to handle structured content for which I have not yet written a detailed parser. In short, it has helped me during development, and whether it survives into the final draft becomes a question of how you want your parser to respond to input that is either not well-formed, or for which the format has changed.

But I digress.

Two of the fun constructs that ship with the Sprache library are the concept of Or, which lets you link alternative elements together, and Return, which lets you substitute anything you want in place of the parsed input.

Using these constructs, it becomes straightforward to write a parser for a range of enum values:

    public static readonly Parser LoadSequence =
        from sequence in Parse.String("preSolution").Token().Return(SectionLoadSequence.PreSolution)
                     .Or(Parse.String("postSolution").Token().Return(SectionLoadSequence.PostSolution))
                     .Or(Parse.String("preProject").Token().Return(SectionLoadSequence.PreProject))
                     .Or(Parse.String("postProject").Token().Return(SectionLoadSequence.PostProject))
                                                    .Or(Parse.Return(SectionLoadSequence.Unrecognized))
        select sequence;

Very expressive.

Parse unique inner content based on an opening token

Another useful construct that ships with Sprache is Then, which lets you determine which expectation follows based on the contents matched in the previous expression.

This is useful in the case of solution files because there are different types of GlobalSection, each with their own inner format.

Take, for example, the difference between a SolutionProperties global section:

    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection

and a ProjectConfigurationPlatforms global section:

    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection

Parsing (and eventually visualizing or manipulating) this last section’s inner content was my whole motivation for parsing solution files in the first place, but looking at the two together it is clear that the parser required to extract relevant details from the ProjectConfigurationPlatforms section would fail to parse a SolutionProperties section.

Luckily, the Then construct takes a lambda accepting the parsed content as an argument, so you can do something funky like this:

    public static readonly Parser GlobalSection =
        from start in Parse.String("GlobalSection").Token()
        from section in RoundBracketedString.Then(s => 
            s == "SolutionProperties" ? SolutionPropertiesGlobalSection
            : s == "SolutionConfigurationPlatforms" ? SolutionConfigurationPlatformsGlobalSection
            : s == "ProjectConfigurationPlatforms" ? ProjectConfigurationPlatformsGlobalSection
                                                   : UnrecognizedGlobalSection(s))
        from end in Parse.String("EndGlobalSection").Token()
        select section;

In between the GlobalSection and EndGlobalSection tags, we first parse the RoundBracketedString that differentiates what kind of global section we’re dealing with. Then we accept the inner content of that round bracketed string and supply different parsers customized for the expected format of each type of section.

Notice again that I have created an UnrecognizedGlobalSection that accepts the section type as an argument. This parser simply swallows everything until the next EndGlobalSection tag, saving it for later use in a diagnostic message while allowing the parsing to continue without exception.

Tip of the iceberg

These two use cases represent just the tip of the iceberg in terms of the possibliies offered by Sprache.

I’m very excited by this library and look forward to using it to explore even more complex grammars.

What content have you had to parse that could benefit from this level of expressiveness?

May 5 / davidalpert

Parsing VS Solution files with Sprache

Anyone who has worked with Visual Studio and more than one branch of active development has been bitten by the friction of merging solution files.

The format of solution files is a bit esoteric, with lots of key=value pairs and guids representing projects, project types, and build configurations. Merging individual lines often requires so much effort that most devs I’ve spoken wtih recommend picking one branch or the other and manually re-constructing the other branch’s changes. Needless to say this work is fidly and error-prone.

Somewhere I got it into my head that building a tool to help this would be a good idea, and apparently I’m not alone in that thought. When sitting down to write this post, I discovered the SLNTools project on codeplex; it looks interesting and I’ll have to try it out.

In the meantime, however, I wanted to share with you a bit about my experience building a parser for solution files using the Sprache library developed by Nicholas Blumhardt.

Some background

The idea behind Sprache is to fill the void between Regular Expression for parsing simple things and using full-blown DSL or parsing toolkits to describe complete grammars on the other.

Sprache takes a functional or parser combinator [PDF] approach; the library provides a set of .NET classes and extension methods that handle low-level parsing jobs like consuming input one character at a time and defining sequence and look-ahead expectations. These tools are exposed as a collection of Parser<T> constructs (where T is the type returned by a successful parse) that can be composed in a declarative style using LINQ query comprehension syntax.

The resulting parser can be very expressive, readable, and testable.

I’ll share some examples as I build up my SolutionFileGrammar below, but here’s a taste to whet your whistle:

public static readonly Parser<SolutionFile> Solution =
        from header in Header
        from projects in Project.Many().Optional()
        from globals in Global
        select new SolutionFile(header, projects, globals);

About Solution Files

In order to define a parser for the Solution File format we have to understand how it is structured.

The best description of solution file syntax I have found is this excerpt: Hack the Project and Solution Files.

Let’s take a look at a empty VS2012 solution file:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Global
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
EndGlobal

And now one with a single project and it’s default build configurations:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpWebAdapters", "HttpWebAdapters\HttpWebAdapters.csproj", "{AE7D2A46-3F67-4986-B04B-7DCE79A549A5}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
EndGlobal

And finally, one with Nuget Package Restore enabled, which adds a solution folder and some freestanding solution items:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpWebAdapters", "HttpWebAdapters\HttpWebAdapters.csproj", "{AE7D2A46-3F67-4986-B04B-7DCE79A549A5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{8374A24A-6031-48CB-8B66-A2B510FA251F}"
ProjectSection(SolutionItems) = preProject
        .nuget\NuGet.Config = .nuget\NuGet.Config
        .nuget\NuGet.exe = .nuget\NuGet.exe
        .nuget\NuGet.targets = .nuget\NuGet.targets
    EndProjectSection
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {AE7D2A46-3F67-4986-B04B-7DCE79A549A5}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
EndGlobal

And now, the parser

In order to parse this with Sprache we need to decompose it into smaller and smaller pieces, build parsers for each of those pieces, then assemble those pieces into a grammar.

We experess that Grammar with a series of static methods that can be built-up test-first by starting with one of the smallest or inner-most pieces of nested content.

For eample, let’s take the header first:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012

The relevant pieces of information are: - a version declaration; and - a product description

Taking that first part, the version declaration, we can focus smaller still on just the version number itself:

[Test]
public void SolutionVersionNumber_is_Number_period_Number()
{
    var input = @"12.00";

    var result = SolutionFileGrammar.SolutionVersionNumber.Parse(input);

    Assert.AreEqual(12, result.Major);
    Assert.AreEqual(00, result.Minor);
}

And write a parser for it:

    public static readonly Parser<SolutionVersionNumber> SolutionVersionNumber =
        from rawMajor in Parse.Number.Token()
        from period in Parse.Char('.')
        from rawMinor in Parse.Number.Token()
        let major = int.Parse(rawMajor)
        let minor = int.Parse(rawMinor)
        select new SolutionVersionNumber(major, minor);

There are a number of things going on here so let’s break it down.

First off we declare a Parser<SolutionVersionNumber> that will return our parsed result and then declare that a SolutionVersionNumber is composed of:

  • A number…

    from rawMajor in Parse.Number.Token()
    
  • …followed by a period…

    from period in Parse.Char('.')
    
  • …followed by a number

    from rawMinor in Parse.Number.Token()
    
  • then I use the let keyword to transform that parsed text into integers

    let major = int.Parse(rawMajor)
    let minor = int.Parse(rawMinor)
    
  • and finally the select keyword to create a new instance of my result:

    select new SolutionVersionNumber(major, minor);
    

Where a SolutionFileVersionNumber is part of our data model:

public class SolutionVersionNumber
{
    public SolutionVersionNumber(int major, int minor)
    {
        Major = major;
        Minor = minor;
    }

    public int Major { get; private set; }
    public int Minor { get; private set; }
}

then came the product name

Now let’s focus on the second piece that we want to parse, the product name:

# Visual Studio 2012

with a test:

[Test]
public void ProductName_is_pound_followed_by_text()
{
    var input = @"# Visual Studio 2012";

    var result = SolutionFileGrammar.ProductName.Parse(input);

    Assert.AreEqual("Visual Studio 2012", result);
}

and a parser:

public static readonly Parser<string> ProductName =
    from pound in Parse.Char('#').Token()
    from name in Parse.AnyChar.Until(NewLine.Or(Eof)).Text()
    select name;

and now the fun begins

Now that we have a simple, tested parser for the version number and another one for the product name, let’s write a test and parser for the whole header:

Given:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012

here’s the test:

    [Test]
    public void Header_contains_version_information()
    {
        var input =
@"Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012";

        var result = SolutionFileGrammar.Header.Parse(input);

        Assert.AreEqual("Visual Studio 2012", result.ProductName);
        Assert.AreEqual(12, result.MajorVersion);
        Assert.AreEqual(00, result.MinorVersion);
    }

the parser:

public static readonly Parser<SolutionFileHeader> Header =
    from ignore1 in Parse.String("Microsoft Visual Studio Solution File, Format Version").Token()
    from version in SolutionVersionNumber
    from name in ProductName
    select new SolutionFileHeader(version, name);

and the object model:

public class SolutionFileHeader
{
    public SolutionFileHeader(SolutionVersionNumber version, string productName)
    {
        MajorVersion = version.Major;
        MinorVersion = version.Minor;
        ProductName = productName;
    }

    public int MajorVersion { get; private set; }
    public int MinorVersion { get; private set; }
    public string ProductName { get; private set; }
}

in conclusion

With that I hope that you can see how expressive a Sprache-based grammar is. It takes a bit of discipline to start with an individual token and grow your grammar test-first, but as your library of tokens grows, the size of your parsers grows also, and before long the declarative and combinatorial nature of Sprache has you moving along at a fast clip.

Full source code for this article, and a more comprehensive (though not yet complete) grammar, is available on github: https://github.com/davidalpert/viper

Apr 21 / davidalpert

NuGet Tip #3:
Manage packages at the solution level

Now that you’ve enabled package restore on build and set up your own package feed it’s time to take a closer look at how we add packages to our projects.

Most .NET developers spend a lot of time in visual studio and are more naturally comfortable with the GUI tooling than with command-line alternatives. The most common way that I see developers adding a NuGet dependency to a project is to right-click on the references node in the solution explorer and select “Manage NuGet Packages…”

right-click on the references node of a project

They pick their package, it downloads, the proper references are added to the project, and off they go.

manage project-level packages

Truthfully, this is all you need to get started and is enough for demos and screencasts, but let’s think about what is happening under the covers.

Under the covers

Once you select a package in the “Manage NuGet Packages” wizard and click install, here is roughly what happens:

  • Visual Studio reaches out through NuGet to download the latest version of the package bits into your packages folder.
  • If your project does not have a packages.config file, an empty one is added to your project.
  • If your packages.config file has an existing reference to an older version of the new package, the old one is removed, including the references into the old package folder.
  • A node describing the package is inserted into the project’s packages.config file
  • A reference into that package folder is added to the project.

There are two things about this process that may get you into trouble over time or on a large project:

  1. by default, nuget installs the latest version available at the time the reference is added.
  2. when nuget adds a package, it adds two independent references, one in the package.config file and one as a reference in the project file.

What’s wrong with the latest version?

On a large project, you often wind up adding new projects over time, often weeks or months apart. If you are always installing packages one project at a time, and a package author happens to release an update in between your two installs, you may wind up with two projects in your solution referencing different versions of a package.

In the best case, the updated package is fully backwards compatible with the old one and the difference may be transparent, or easily fixable with binding redirects. In the worst case, however, an upgraded package by contain breaking changes or expose a completely different API. Additionally, I have noticed that ClickOnce installs will fail if they contain two instance of the same assembly that are stamped with different version information.

When using nuget on the command line or in the powershell console inside visual studio you have options for specifying a specific version of a package, but no such luck in the “Manage NuGet Packages” dialog. So how to encourage our GUI-bound brothers and sisters to use consistent package versions across a project? Train them to manage packages at the solution level, as I explain below.

Where is my package reference?

Another quirk of the “Manage Package References” dialog is that its “Installed Packages” list appears to populate from the package.config file, ignoring completely any references that you have in your project. If for some reason you edit your packages.config file and remove a node, the visual studio tooling will no longer include that package under the installed list in the “Manage Package References” dialog nor will it restore that package on build, even if the reference in the project file remains pointed into the package folder.

Manage packages at the solution level

A good rule of thumb that addresses both of these issues is to always manage packages at the solution level. Right-click on the Solution node in the Solution Explorer and select “Manage NuGet packages for Solution“.

right-click on the solution node

The solution-level “Manage NuGet Packages” dialog is nearly identical to the project-level “Manage NuGet Packages” dialog, but instead of “Install” buttons you get “Manage” buttons and a list in the bottom part of the right-hand column of which projects have that package installed.

manage solution-level packages

Clicking on the “Manage” button will open a “Select Projects” dialog with a list of projects in your solution and checkboxes beside each one.

select projects

Check off the projects into which you want to install the new package, or check off new projects that you want to add this package to, click OK, and Visual Studio will loop through the projects uninstalling or installing the package based on the checkmark.

Were are my installed packages?

Similar to the project-level package dialog, this solution-level one has a quirk of its own. Rather than reading the packages.config files of each project in your solution, the “Installed” tab appears to populate based on scanning the packages folder of your project source files.

This means that if you have enabled package restore and not checked any projects into source control, a running this dialog after a fresh checkout will show you that no packages are installed.

As well, if you have been working with a solution over time and upgraded a package once or twice along the way, each version of that package that is living in the packages folder of your source files will appear in the “Installed” list of the solution-level packages dialog.

Apr 7 / davidalpert

This is me in grade 9; or
Nothing is real

To follow in the footsteps of fellow blogger Steve Rogalsky, this week I’d like to share with you a moment from my grade 9 chemistry class that changed forever the way that I learn and communicate.

I can still go back to that day, sitting in a school room on the west side of Montreal, watching Martin Hardiman draw circles around circles on a chalkboard and natter on about electrons, protons, and the periodic table.

Suddenly, he stopped writing.

Turning around, he said, “None of this is real.”

Dead silence.

Just like that he had all of our attention.

Bless his heart, for he went on to say something like this:

“We spend all this time teaching you about the structure of atoms and electrons and protons and chemical compounds and yet none of it is real; it’s only a model that approximates reality. In fact, there is no way to know what the structure of an atom actually looks like, in reality, because the act of looking at it changes it. Sometimes an electron behaves like a particle, sometimes it behaves like a wave. Is it either? I don’t think so. I think it’s something else entirely. The important thing is to remember is that both a particle and a wave are metaphors for this unapproachable reality. It can be useful to think in terms of models and metaphors because they allow us to understand and predict the behavior of the world around us, but don’t for a moment forget that models and metaphors are not, themselves, real.”

In the end, this concept helped to realize that the world that that I see is not the world that actually exists, but only my perception of it. Furthermore, the world that I perceive may differ wildly from the world that you perceive, and that is where life gets interesting.

When someone disagrees with me, that usually means that their mental model differs from mine. I find it helps to remember that neither of us is arbitrarily right or wrong, because it often leads me right into the more interesting questions about the impact or usefulness of my way of thinking, the other way of thinking, or sometimes even suggests an entirely new way of thinking.

Thank you, Martin. May you rest in peace knowing that you made a profound difference, well beyond the subject matter, on at least one of your students.