In-Depth

Recalculate VS.NET Project Dependencies Automatically

You can build a macro that recalculates and sets assembly dependencies upon request with the VS.NET automation model, even if your solution uses file references.

You can add two kinds of references to other assemblies in a VS.NET project: Project and File. In the first case, you add a reference to another project present in the solution you're working with. In case of File references, you pick up the compiled assembly from the file system.

Using Project references is usually recommended because VS.NET offers additional RAD features that are unavailable when you use File references. When you work with Project references, VS.NET calculates and maintains the correct build order among the projects present.

VS.NET doesn't switch from a Project reference to a File reference when an assembly is removed from the solution (as VB6 does). While File references are owned by projects, Project references are owned by the solution. Suppose you define a project reference in assembly X to assembly Y in solution Z. Now try pulling the same assemblies together in a new solution: Project references set in the previous solution are gone.

Microsoft guidelines recommend keeping all the assemblies in a single solution using Project references to link projects each other. However, when the number of assemblies you must hold within a solution grows significantly, you can't follow this approach anymore because memory issues bog down VS.NET.

The alternative at this point is to work with ad-hoc solutions that contain a subset of the application assemblies required for the current development or debugging session. It's clear that in this situation, you must start using file references or you'll need to reset all assembly reference each time.

Fortunately, thanks to the VS.NET automation model, you can easily come up with a macro that recalculates and sets assembly dependencies upon request, even if the solution uses File references. First, remove all existing build dependencies:

Public Sub CalcBuildDepends()
	Try
		Dim l_bd As BuildDependency
		For Each l_bd In _
			DTE.Solution.SolutionBuild.BuildDependencies
			l_bd.RemoveAllProjects()
	Next

The DTE variable contains the applicationobject, which is the root of the VS.NET automation model. VS.NET injects this variable automatically into the macro execution context. At this point, extract each project's file references list and assembly name:

For Each l_prac As EnvDTE.Project In _
			DTE.Solution.Projects
			Dim l_ActVSProject As _
				VSLangProj.VSProject = _
				l_prac.Object
		Dim l_actprjAssemblyName As String = _
			l_ActVSProject.Project.Properties.Item( _
			"AssemblyName").Value.ToString

For each reference in the active project, scan the project list and try to match the reference name with the project assembly name. If you find a match, add to the active project a reference to the project being examined in the inner project loop:

		For Each ref As VSLangProj.Reference In _
			l_ActVSProject.References
			For Each l_pr As EnvDTE.Project In _
				DTE.Solution.Projects
			Dim l_VSProject As VSLangProj.VSProject = _
				l_pr.Object
			If (l_pr.Properties.Item( _
				"AssemblyName").Value.ToString= _
				ref.Name) _
				Then
					Try
				DTE.Solution.SolutionBuild. _
					BuildDependencies.Item( _
					l_ActVSProject.Project). _
					AddProject(l_pr.UniqueName)
			Catch ex As System.Exception
				MessageBox.Show( _
					"Error adding dependency " + 
					l_pr.UniqueName + _  
					" to " + 
					l_ActVSProject.Project.Name + 
					" Error is:" + _
					ex.Message)
			End Try
		End If
	Next

Finally, close the loops and the outer Try block:

			Next
		Next
		MessageBox.Show("Recalculation Done")
	Catch ex As System.Exception
		MessageBox.Show("Error in seek:" + ex.Message)
		End Try
	End Sub

Add this subroutine to a macro module and link it to a custom entry of the tools menu so you can call it with a click of the mouse. To add this custom entry to the Tools menu, select Tools | Customize, choose the Command tab, and select Macro from the listbox on the left. Scroll down the listbox on the right until you find the macro you just created. Drag it on the Tools menu, which opens up again to let you insert the new command where you like within the pre-existing menu entries. If you like, assign more meaningful text to the menu entry and an icon as well.

comments powered by Disqus

Featured

Subscribe on YouTube