Upgrade projects with shared files

When migrating projects with shared files, it is essential to consider how the upgrade process will generate these files. The generated code may likely include compiler directives identifying which lines of code belong to which project. These directives ensure that specific code sections are only executed depending on the building or execution of the project.

C# Example

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated.
#if Project01
namespace Project01
#elif Project02
namespace Project02
#elif Project04
namespace Project04
#elif Project03
namespace Project03
#endif
{
	internal static class SharedModule01
	{

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated.
#if Project01
		internal static object PrimitiveSharedTest01(object p1) => Module01.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<string>(p1));

#elif Project02
		internal static object PrimitiveSharedTest01(object p1) => Module02.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<bool>(p1));

#elif Project03
		internal static object PrimitiveSharedTest01(object p1) => Module03.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<int>(p1));

#elif Project04
		internal static object PrimitiveSharedTest01(object p1) => Module04.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<double>(p1));

#endif
	}
}

VB.NET Example

Option Strict Off
Option Explicit On
Imports System
Imports UpgradeHelpers.Helpers
Module SharedModule01
	Public Function PrimitiveSharedTest01(ByVal p1 As Object) As Object
'UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated. More Information: https://docs.mobilize.net/vbuc/ewis/notes#id-1707
#If Project01 Then
		Return PrimitiveTest01(ReflectionHelper.GetPrimitiveValue(Of String)(p1))
#ElseIf Project02 Then
		Return PrimitiveTest01(ReflectionHelper.GetPrimitiveValue(Of Boolean)(p1))
#ElseIf Project03 Then
		Return PrimitiveTest01(ReflectionHelper.GetPrimitiveValue(Of Integer)(p1))
#ElseIf Project04 Then
		Return PrimitiveTest01(ReflectionHelper.GetPrimitiveValue(Of Double)(p1))
#End If
	End Function
End Module

However, these files may be affected depending on how the user wants to migrate the code; whether migrating the entire solution or just a few projects.

Upgrade Approaches: Entire solution or Selected Projects

When performing an upgrade, there are two options: upgrading the entire solution (Upgrade Projects button) or selected projects (Upgrade Selection button):

Upgrading the Entire Solution

Upgrading the entire solution is ideal when it's necessary for most or all projects to be upgraded and updated simultaneously. Upgrading the solution eliminates the risk of incomplete migrations or mismatched shared file versions across projects. This guarantees that all files, including shared ones, are synchronized across the solution.

Upgrading Selected Projects

Sometimes, you may only need to migrate specific projects rather than the entire solution. This is particularly useful when only a subset of the projects wants to be updated. This option is typically selected when remigrating some projects, rather than the entire solution.

However, when selecting projects to upgrade, there’s an additional step that can help manage shared files. If there are shared files in unselected projects that are also included in the selected ones, the VBUC will display a window, showing a list of the shared files along with the unselected projects.

Identifying Projects with Shared Files

In case the user selects projects, and the solution contains other projects with shared files and were not selected, the VBUC will display a window with the following elements:

  1. A list of shared files: This shows all the files that are accessible by more than one project.

  2. Projects that share each file: For each shared file, it will display a list of the unselected projects who use it.

This information is crucial in determining which projects need to be upgraded together to avoid issues in the generated share files.

  • It is always recommended that the entire solution be upgraded. Although it may take longer to complete, it eliminates the risk of version mismatches between projects and ensures that all shared files are up-to-date. Here is an example of the resulting file by migrating the entire solution:

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated.
#if Project01
namespace Project01
#elif Project02
namespace Project02
#elif Project04
namespace Project04
#elif Project03
namespace Project03
#endif
{
	internal static class SharedModule01
	{

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated.
#if Project01
		internal static object PrimitiveSharedTest01(object p1) => Module01.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<string>(p1));

#elif Project02
		internal static object PrimitiveSharedTest01(object p1) => Module02.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<bool>(p1));

#elif Project03
		internal static object PrimitiveSharedTest01(object p1) => Module03.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<int>(p1));

#elif Project04
		internal static object PrimitiveSharedTest01(object p1) => Module04.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<double>(p1));

#endif
	}
}
  • If you want to migrate specific projects within the solution and they contain shared files, and the VBUC doesn't display an additional window related to the list of shared files, you can proceed without taking further action. However, if the window does appear, copy the list from the window into a notepad, click the 'No' button, and also select the projects listed. In the example below, we have a solution with 4 projects, each sharing the file SharedModule01.bas; since we select 3 projects, a new window will appear showing the list of the unselected projects that share files.

In this case, we will continue the process without including the missing project to see what happens with the shared file.

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated. More Information: https://docs.mobilize.net/vbuc/ewis/notes#id-1707 
#if Project03
namespace Project03
#elif Project01
namespace Project01
#elif Project02
namespace Project02
#endif
{
	internal static class SharedModule01
	{

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated. More Information: https://docs.mobilize.net/vbuc/ewis/notes#id-1707
#if Project01
		internal static object PrimitiveSharedTest01(object p1) => Module01.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<string>(p1));

#elif Project02
		internal static object PrimitiveSharedTest01(object p1) => Module02.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<bool>(p1));

#elif Project03
		internal static object PrimitiveSharedTest01(object p1) => Module03.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<int>(p1));

#endif
	}
}

As we can see, it does generate the code for the 3 projects; however, since the missing project was not included in this process, it is likely to have a different behavior than if all the necessary projects had been migrated. Below is the code if all projects containing shared files had been selected.

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated.
#if Project01
namespace Project01
#elif Project02
namespace Project02
#elif Project04
namespace Project04
#elif Project03
namespace Project03
#endif
{
	internal static class SharedModule01
	{

//UPGRADE_NOTE: (1707) The resulting shared file would differ depending on whether all or some of the projects are migrated.
#if Project01
		internal static object PrimitiveSharedTest01(object p1) => Module01.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<string>(p1));

#elif Project02
		internal static object PrimitiveSharedTest01(object p1) => Module02.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<bool>(p1));

#elif Project03
		internal static object PrimitiveSharedTest01(object p1) => Module03.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<int>(p1));

#elif Project04
		internal static object PrimitiveSharedTest01(object p1) => Module04.PrimitiveTest01(ReflectionHelper.GetPrimitiveValue<double>(p1));

#endif
	}
}

When migrating all projects that contain shared files, the shared files window will not be displayed, so the result would be the same as if the entire solution had been migrated.

Last updated

Was this helpful?