views:

179

answers:

5

I'm currently working on a web project that involves several assemblies, structured something like this:

WebProject
 |
 +--> A (external assembly, Version 1.0.0.0)
 |
 +--> B (external assembly, Version 1.0.0.0)

The difficulty is that in order to keep track of what's deployed, I'd like to updated the version numbers of assemblies A and B at each build. Right now I'm doing that with the [assembly: AssemblyVersion("1.0.*")] technique, but it wreaks havoc in the WebProject project, because it contains a number of ASP.NET pages and master pages that refer to types in assemblies A and B.

Is there a simpler way to update these references other than manually?

Update: assemblies A & B live in one solution, while WebProject lives in another. Also, A & B are strongly named because they get deployed to IIS/SharePoint servers.

+1  A: 

Are you referencing the compiled assemblies directly? Consider adding them to your solution and including them as project references.

If you do it right, this will work with assemblies that are used by multiple applications, as well, since each "parent" solution can contain the references. Of course, this leads to the inevitable challenge of knowing "does this change break any other applications" which requires a fair amount of planning. This problem is eased a bit by coding to interfaces and/or abstract classes and treating any change in signature that can't be accomplished via an overload as a "breaking change", requiring regression on the other applications that use those assemblies.

joseph.ferris
+1  A: 

With project references within the same solution, this is done automatically.

If A and B are not in the same solution, then you can set the references to them to not require a specific version (look in the reference properties) - but beware that this is for compile time only, so you will still need to recompile the web project when A or B updates.

Failing that you could possibly look into assembly binding redirection.

David M
A: 

Turns out I found a blog describing a way to use the subwcrev tool included with TortoiseSVN to replace 1.0.0.$REV$ with 1.0.0.25 or whatever. That pretty much does what I want. It's sane.

Ben Collins
That will work until your revision exceeds a UInt16 (65535)
hometoast
Let's assume I make 10 commits a day. I don't, but let's assume. I'll have 6,553 days before this is a problem. That gives me 18 years to figure out something different.
Ben Collins
A: 

I use a powershell script to do the same, independent of the use of SVN or any particular version control system.

# SetVersion.ps1
#
# Set the version in all the AssemblyInfo.cs or AssemblyInfo.vb files in any subdirectory.
#
# usage:  
#  from cmd.exe: 
#     powershell.exe SetVersion.ps1  2.8.3.0
# 
#  from powershell.exe prompt: 
#     .\SetVersion.ps1  2.8.3.0
#
# last saved Time-stamp: <2009-February-11 22:18:04>
#


function Usage
{
  echo "Usage: ";
  echo "  from cmd.exe: ";
  echo "     powershell.exe SetVersion.ps1  2.8.3.0";
  echo " ";
  echo "  from powershell.exe prompt: ";
  echo "     .\SetVersion.ps1  2.8.3.0";
  echo " ";
}


function Update-SourceVersion
{
  Param ([string]$Version)

  $NewVersion = 'AssemblyVersion("' + $Version + '")';
  $NewFileVersion = 'AssemblyFileVersion("' + $Version + '")';

  foreach ($o in $input) 
  {

    #### !! do Version control checkout here if necessary 
    Write-output $o.FullName
    $TmpFile = $o.FullName + ".tmp"

     get-content $o.FullName | 
        %{$_ -replace 'AssemblyVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)', $NewVersion } |
        %{$_ -replace 'AssemblyFileVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)', $NewFileVersion }  > $TmpFile

     move-item $TmpFile $o.FullName -force
  }
}


function Update-AllAssemblyInfoFiles ( $version )
{
  foreach ($file in "AssemblyInfo.cs", "AssemblyInfo.vb" ) 
  {
    get-childitem -recurse |? {$_.Name -eq $file} | Update-SourceVersion $version ;
  }
}


# validate arguments 
$r= [System.Text.RegularExpressions.Regex]::Match($args[0], "^[0-9]+(\.[0-9]+){1,3}$");

if ($r.Success)
{
  Update-AllAssemblyInfoFiles $args[0];
}
else
{
  echo " ";
  echo "Bad Input!"
  echo " ";
  Usage ;
}
Cheeso
+1  A: 

In the build process at Cedaron, we maintain the references in the Web Project by copying them into the Web Project's bin directory by the build script instead of declaring the references.

You wouldn't think that would work, but it does. If they are in the bin directory, you can use them.

Joshua