Compatibility Across Versions: Multi-Targeting in Umbraco 10 and 13 Package Development

Released on December 14, 2023, Umbraco 13 is the next long-term supported (LTS) version, built on the latest Microsoft .NET framework, specifically .NET 8 and ASP.NET Core 8, and utilizes C# 12.

At my company TRES, we only support LTS versions because they are supported for longer periods and don't contain experimental features.

We currently use Umbraco in versions 8 and 10, meaning we are already on LTS versions. This is great for our ongoing projects, but for new projects, we need to transition to version 13. Therefore, we need to upgrade our template to quickly generate a basic website.

But how do we start?

One of the steps was to ensure our extension packages were compatible with Umbraco 13. However, since we also want to support Umbraco 10, we aimed to avoid duplicating our code bases. The solution was multi-targeting. For Umbraco 8 we have a completely different baseline so we only want to focus on our Umbraco 10 packages to also be compatible with Umbraco 13

What is Multi Target?

With Multi-Target, we can include two different versions of NuGet packages in our project, allowing us to support both Umbraco 10 and 13. The packages we are building are extensions for Umbraco to support rendering logic. Or to give a developer a generic search base class to be extended in the project. But how can we target this for multiple versions?

But how do we achieve this, Let's look at an example, and I will explain.

 

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<Nullable>enable</Nullable>
		<ImplicitUsings>enable</ImplicitUsings>
		<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
		<Product>Package Product Name</Product>
		<PackageId>Umbraco.Community.Package</PackageId>
		<Title>Umbraco.Community.Package</Title>
		<Description>Example Community Package for multi target</Description>
		<PackageTags>umbraco package</PackageTags>
		<Company>TRES</Company>
		<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
		<Version>1.0.0$(VersionSuffix)</Version>
	</PropertyGroup>

	<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
		<PackageReference Include="Umbraco.Cms" Version="10.8.1" />
	</ItemGroup>

	<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
		<PackageReference Include="Umbraco.Cms" Version="13.0.0-*" />
	</ItemGroup>

</Project>


First in your Csproj file change the framework that is supported. by changing the line from Framework to Frameworks

 

<TargetFrameworks>net6.0;net8.0</TargetFrameworks>

Next, add an if statement in your Csproj to work for a specific .NET version.

<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
	<PackageReference Include="Umbraco.Cms" Version="10.8.1" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
	<PackageReference Include="Umbraco.Cms" Version="13.0.0-*" />
</ItemGroup>

Here we define the possibility to target a.NET version and then load the correct packages. This way we can load Umbraco 10 for .NET 6 and Umbraco 13 for .NET 8.

So now we can build our logic for all the LTS versions we want.

The same can be done in your code. Maybe namespaces are different or a referenced package has been rewritten so you need to change the logic. This can be done with similar #if statements. See the example within a C# file.

 

#if NET6_0
	//Specific code for .NET 6
#endif
#if NET8_0
	//Specific code for .NET 8
#endif

So this is a basic example of muli-targeting using Umbraco 10 and 13 as an example. This also can be done for only Core projects.

And if you need more information or help please contact me using my socials.