4

I have a solution consisting of a number of projects, including:

Foo.Bar.Client
Foo.Common

Foo.Bar.Client depends on components in Foo.Common. And, Foo.Common does not have its own config file; its settings are stored in the config file of the client app using it, in this case Foo.Bar.Client.
Thus, the config file for Foo.Bar.Client contains

  <configSections>
    <section name="BletchConfiguration" 
             type="Foo.Common.Bletch, Version=1.1.0.0, ..."/>
    ....
  </configSections>

I've been tasked with tweaking our version numbering so that the "revision" portion corresponds to the latest change-set (in our case the HEAD revision number, as we're using Subversion), e.g. from "1.1.0.0" to "1.1.0.12345".

So I've implemented a "shared" assembly-version-info module as described here. And I've modified our NAnt build script to grab the version number and update the shared assembly-info file.

I had not, however, counted on version numbers being embedded in the config file(s). Is there a (relatively) painless way to automate updating the version numbers in the config files?

Obviously, I can split the "common" assembly into a separate solution.
I could also configure the common components using IoC, which would eliminate the need for an assembly-specific config section.
However, either of these approaches involve some risk and time ... both of which I believe the powers-that-be would prefer to avoid if possible (at least for right now).

David
  • 2,226
  • 32
  • 39

2 Answers2

2

Quick answer - unless you are supporting multiple simultaneous versions of Foo.Common.dll in your application, I would just omit the version number from the configuration section.

<configSections>
    <section name="BletchConfiguration" 
         type="Foo.Common.Bletch, Foo.Common"/>
    ....
</configSections>

This isn't special to the 'section' area of the config file structure - this is an inherent .net thing - and a convention used all over.

[EDIT]

I cannot locate any documentation specifically relating to which parts are optional. MSDN documentation simply states the structure http://msdn.microsoft.com/en-us/library/ms228245.aspx However, from memory and a little experimentation... (it's quite flexible - square brackets means optional)

If your DLL is in the GAC - you will need the Version... FullTypeAndNamespace, AssemblyNameWithoutExtension, Version, Culture, PublicKeyToken [,PlatformType]

If your DLL is in the bin directory FullTypeAndNamespace, AssemblyNameWithoutExtension [,Version, Culture, PublicKeyToken] [,PlatformType]

Hence the first two parts are mandatory, because the application needs to know what assembly to look in, for the type you have specified.

You can have the optional components in any order, (because they are structured as key=value pairs, order doesnt matter). Simply specify the elements that you want to constrain, omit the rest.

So, in the example I have given, the CLR will load the first DLL that matches the name, and contains the required type.

Adam
  • 4,159
  • 4
  • 32
  • 53
  • You wouldn't be able to point me to some documentation, would you? I've been thinking (and searching) along those lines but I haven't found anything to indicate what portions of the `type` can be omitted and when. – David Nov 22 '11 at 13:57
1

I would not rev my AssemblyVersion that often. You should be reving the AssemblyFileVersion for each build (so you can tell them apart) but reving the AssemblyVersion each build is quite problematic.

What are differences between AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion?

EDIT: When I do have to update the AssemblyVersion, I run a Powershell script that finds the files that need to be modified, checks them out and makes the change. I manually submit the changes after verifying a subset of the files.

Here is the script to update the actual AssemblyVersion:

get-childitem . -rec -include AssemblyInfo.cs | select-string "assembly: AssemblyVersion(" -simplematch -list | % { & p4 sync $_.path; & p4 edit $_.path; (get-content $_.Path) |% { $_ -replace "assembly: AssemblyVersion\(`"\d\.\d\.\d\.\d", "assembly: AssemblyVersion(`"2.0.0.0" } | set-content $_.Path -Encoding UTF8 }

Here is one to update a projects reference from 1.5.0.0 to 2.0.0.0:

get-childitem . -rec -include *.csproj | select-string "<Reference Include=`"Acme.SomeProduct," -simplematch -list | % { & p4 sync $_.path; & p4 edit $_.path; (get-content $_.Path) |% { $_ -replace "<Reference Include=`"Acme\.SomeProduct, Version=1\.5\.0\.0,", "<Reference Include=`"Acme.SomeProduct, Version=2.0.0.0," } | set-content $_.Path -Encoding UTF8 } 
Community
  • 1
  • 1
Russell McClure
  • 4,821
  • 1
  • 22
  • 22
  • I also agree with this. We rev the file version per-build, and only change assembly identity when we make a release. However - regardless of how often you change it - if you have the version number in your config - it will probably catch you out at some point. Suzanne Cooke makes the recommendation that you change assembly version before beginning development on a release (http://blogs.msdn.com/b/suzcook/archive/2003/05/29/when-to-change-file-assembly-versions.aspx), rather than just before release - for good reason - changing assembly identity affects the behavior of your application. – Adam Nov 22 '11 at 21:54
  • That makes a lot of sense. Unfortunately some of the `.config` references are being passed to an (older) Enterprise Library block, which _requires_ a four-part assembly version number, i.e. major.minor.build.revision. – David Nov 23 '11 at 14:26
  • @Russell - Thanks for the response ... I had a really hard time picking an answer to "accept". I am in awe of your PowerShell-fu. – David Nov 23 '11 at 22:40