Friday, July 20, 2007

Strongly-named assemblies and InternalsVisibleTo

One of the projects I work on wasn’t using strongly-named assemblies, so we decided to sign them (mainly to prevent version conflicts on sales laptops). However, after generating the key-pair and setting up the different assemblies to use it, building the solution gave this error:

Friend assembly reference ‘Company.Product.UnitTests’ is invalid. Strong-name signed assemblies must specify a public key token in their InternalsVisibleTo declarations.

The problem was that some of the assemblies were making their internals visible to the UnitTests assembly (making them accessible so that they could be tested), but when these assemblies are strongly names, the public key token must also be included in the InternalsVisibleTo declaration in Assembly.cs.

This introduces a chicken-and-egg scenario; the A assembly makes its internals visible to the UnitTests assembly, but must know the UnitTests assembly public key in order to build. The UnitTests assembly depends on assembly A to build, but assembly A can’t be built until we know what the public key token for UnitTests is, which in turn can’t build because it depends on assembly A…

After looking into a couple of solutions, the one that worked for me was:

  1. Sign all assemblies with the key-pair
  2. Generate the public key for the key-pair as such (from the Visual Studio command prompt):

    sn -p path\to\keypair.snk path\to\keypair.pub

  3. Get the public key token for the public key as such (still from the Visual Studio command prompt):

    sn -tp path\to\keypair.pub

    This will output a long (256 characters) public key; copy this to the clipboard

  4. Declare the InternalsVisibleTo attribute in Assembly.cs as such:

    [assembly: InternalsVisibleTo("Company.Product.UnitTests, PublicKey=<your public key>")]

    where <your public key> is replaced by the public key output in (3)

  5. Build the solution. The solution should now build as expected.

This assumes that all assemblies use the same key-pair - suggestions to use the public key token (using PublicKeyToken=... rather than PublicKey=...) didn’t work for me.

posted by Nick at 5:58 pm - filed in .net  

Friday, July 13, 2007

Rubyists and Photographers

I was browsing the net the other day, minding my own business, when I came across this:


In summary, Jared Carroll is proposing to replace

def update_subscriptions
  Subscription.find(:all).each do |each|
    if each.expired?


def update_subscriptions
  subscriptions = Subscription.find :all
  expired = subscriptions.select {|each| each.expired?}
  expired.each {|each| each.renew!}
  active = subscriptions.reject {|each| each.expired?}
  active.each {|each| each.update!}

in the name of avoiding conditionals in Ruby. You’ll notice that the second version loops through the ’subscriptions’ array 3 times rather than one. In the comments (which span 9 A4 pages) follows a lengthy discussion on the aesthetics and validity of the design of the second solution. It struck me then that Ruby gives you power, a lot of power - perhaps, sometimes, too much power.

I’m reading Paul Graham’s Hackers and Painters at the moment, and continue with his “hacking is like a visual art” analogy, I’d like to propose the following: Ruby is to Java (or C#) what photography is to oil painting. As with all analogies, it has its limitations, but the logic is as follows:

  • creating an image using oil painting is long and hard
  • creating an image using photography is quick and easy
  • because creating an image is quicker with photography, the amount of time spent actually creating the image becomes a proportionally smaller part of the artistic process than it is with oil painting
  • as a result, the percentage of time spent on ’secondary’ considerations (lenses, film types, darkroom exposure techniques, filters, etc.) becomes a proportionally larger part of the artistic process

Most of the professional photographers I know actually spend little time thinking about the secondary considerations such as lenses, film types etc. - they seem to find something they like and stick with it, reviewing their choices only occasionally. However, some get tempted into spending a lot of time and energy debating the relative merits of different lenses, film types, darkroom exposure techniques etc. These items are still only a minor factor of a good picture; the most important element in a good picture is unarguably its content (in a studio picture, this could be the subject, angle, background, lighting, pose etc.)

The similarity here, I think, is that Ruby has empowered programmers to think about the lenses, film types etc. a lot more because taking a picture has just become so much easier. There is not doubt in my mind, however, that whether to use conditional logic or closures is a minor consideration compared to the main (and hardest to attain) aim of the hacker, which is the beauty of the resulting solution; as tempting as it may be to debate the best polarizing filter, debates about language constructs are only as valuable as their contribution to achieving that aim is (which in this case would probably be minor).

P.S. I’m not at all arguing that Jared Carroll or any of the commenters in his blog are bad programmers (most of them are probably more experienced and talented than I am), or that debating about lenses and cameras is pointless - it isn’t, but spending more time thinking about them than actually taking pictures is counter-productive for a photographer. I’m just reminding myself how easy it it to get sidetracked.

posted by Nick at 12:53 pm - filed in ruby  

Thursday, July 5, 2007

Multiple Monitors using Windows Remote Desktop

One of the main limitations of Microsoft’s Remote Desktop client (Terminal Services Client) was its inability to span multiple monitors. This limitation has been fixed in the latest version of Remote Desktop client (v6.0); in my case, this means I can connect to a remote Windows workstation from my home machine and have the remote desktop span both of my monitors, which helps productivity no end. To do this, the latest version of Remote Desktop client is required:

(for Windows XP - it is bundled with Vista)

You can then start remote desktop up to span multiple monitors via the command line:

mstsc.exe /w:2560 /h:1024 /v:<server>

Or by editing the .rdp file in Notepad:


Gives this:


posted by Nick at 10:57 am - filed in windows