Skip to main content
All docs
V25.1

DevExpress v25.1 Update — Your Feedback Matters

Our What's New in v25.1 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

Share Code Between Legacy .NET Framework and Modern .NET Apps

  • 3 minutes to read

Migrating a WinForms application from .NET Framework 4.7.2+ to .NET 8+ can be a complex and time-consuming process. Legacy dependencies, API changes, and platform differences require extensive testing before the .NET version is production-ready. To ensure business continuity, many teams choose to maintain both .NET Framework and .NET versions in parallel until the migration is fully tested.

This help topic outlines strategies to manage both versions while maximizing code reuse. To support both .NET Framework and .NET 8+, consider one of the following strategies:

Multi-targeting in a single project
Recommended for libraries and shared components.
Two separate project files (.csproj) sharing a common .props file
Useful for applications with different build settings or dependencies.

Tip

Analyze Dependencies

  • Identify dependencies that are not compatible with .NET.
  • Update NuGet packages to versions that support both .NET Framework and .NET 8+.
  • Replace deprecated APIs with cross-platform alternatives.

#Multi-Targeting in a Single Project

Use SDK projects and target multiple frameworks in a single .csproj file to maintain a unified codebase. This technique can be used for libraries and components that must work across both frameworks.

  • TargetFrameworks specifies multiple targets.
  • Conditional package references include only necessary dependencies per target.
xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFrameworks>net8.0-windows;net472</TargetFrameworks>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="DevExpress.Win" Version="25.1.3" />
  </ItemGroup>

  <ItemGroup Condition='$(TargetFramework)' == 'net472'”>

  </ItemGroup>

</Project>

Note

Visual Studio supports design-time editing for only one target framework at a time in multi-targeted projects. It uses the first framework listed in the TargetFrameworks property. The following setting forces Visual Studio to use the .NET (Core-based) WinForms Designer:

<TargetFrameworks>net8.0-windows;net472</TargetFrameworks>

To use the .NET Framework Designer instead, reverse the order:

<TargetFrameworks>net472;net8.0-windows</TargetFrameworks>

Use #if directives to separate framework-specific implementations:

C#
string GetEnvironmentInfo() {
#if NET472
  return "Running on .NET Framework";
#elif NET8_0_OR_GREATER
  return "Running on .NET 8+";
#else
  return "Unknown Framework";
#endif
}
Pros Cons
Maintains a single project structure. Larger project files with multiple conditions.
Easier code maintenance and refactoring. Some dependencies may not support multi-targeting.
Centralized build process. Build tools must support SDK-style projects (VS 2019+).

#Separate Projects with a Shared ‘.props’ File

For applications requiring different build configurations or dependencies, use two .csproj files that import a shared .props file:

  • Shared properties are defined in DXApplication.Shared.props.
  • Separate .csproj files allow you to use distinct dependencies and settings.

The application structure is usually as follows:

/DXApplication/
├── DXApplication.NET.csproj
├── DXApplication.FW.csproj
├── DXApplication.Shared.props
└── /Shared/       (actual code files)
<Project>
    <ItemGroup>
        <Compile Remove="obj*\**"/>
        <None Remove="obj*\**"/>
        <Content Remove="obj*\**"/>
        <None Remove="DXApplication.Shared.props"/>
    </ItemGroup>
    <ItemGroup>
        <PackageReference Include="DevExpress.Win" Version="25.1.3"/>
    </ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
  <Import Project="DXApplication.Shared.props" />

  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <OutputType>WinExe</OutputType>
    <UseWindowsForms>true</UseWindowsForms>
    <BaseIntermediateOutputPath>obj.FW</BaseIntermediateOutputPath>
  </PropertyGroup>

</Project>
<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="DXApplication.Shared.props" />

  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <OutputType>WinExe</OutputType>
    <UseWindowsForms>true</UseWindowsForms>
    <IntermediateOutputPath>obj.NET</IntermediateOutputPath>
  </PropertyGroup>

</Project>
Pros Cons
More control over framework-specific configurations. Requires managing multiple project files.
Clear separation of dependencies and build settings. Possible code duplication.
Easier debugging and targeted optimization per framework. More complex build and deployment pipelines.

#See Also