Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a2bb104
Update with the minimal changes needed to align existing content to t…
StephenBonikowsky Jun 10, 2021
bc00ae7
Merge branch 'dotnet:main' into migrationdocsphaseone
StephenBonikowsky Jun 10, 2021
0d830c9
Adding the new page 'tooling-requirements.md' and adding initial cont…
StephenBonikowsky Jun 10, 2021
84c4cf4
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 10, 2021
60e6e19
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 10, 2021
1dc7471
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 10, 2021
0dd1b9f
Created additional pages needed for Phase 1 modifying the TOC as needed.
StephenBonikowsky Jun 10, 2021
f634263
Created additional pages needed for Phase 1 modifying the TOC as needed.
StephenBonikowsky Jun 10, 2021
f3b29c7
Fixed merge conflicts.
StephenBonikowsky Jun 11, 2021
9174190
Update docs/core/porting/premigration-needed-changes.md
adegeo Jun 11, 2021
fa12a00
Update docs/core/porting/premigration-needed-changes.md
adegeo Jun 11, 2021
2b965ec
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 11, 2021
3045cb0
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 11, 2021
56d1820
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 14, 2021
f1fb91e
Add breaking change page.
StephenBonikowsky Jun 14, 2021
1995634
Add breaking change page.
StephenBonikowsky Jun 14, 2021
4152705
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 14, 2021
8d45d92
Update tooling requirements page based on feedback.
StephenBonikowsky Jun 23, 2021
7b0dd18
Merge branch 'main' of https://github.com/dotnet/docs into migrationd…
StephenBonikowsky Jun 23, 2021
1f15770
Update breaking changes page.
StephenBonikowsky Jun 25, 2021
2cbeaae
Update breaking changes page.
StephenBonikowsky Jun 25, 2021
0644cd8
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 25, 2021
b05056c
Rename and move thepage about sdk, msbuild and vs versioning.
StephenBonikowsky Jun 25, 2021
7706464
Rename and move thepage about sdk, msbuild and vs versioning.
StephenBonikowsky Jun 25, 2021
69a2469
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jun 25, 2021
603d505
Latest round of feedback updates.
StephenBonikowsky Jul 1, 2021
b901e9e
Latest round of feedback updates.
StephenBonikowsky Jul 1, 2021
88dfd5a
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jul 1, 2021
944be85
Update docs/core/porting/breaking-changes.md
StephenBonikowsky Jul 1, 2021
1fc212b
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jul 1, 2021
a397ff7
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jul 1, 2021
415de72
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jul 1, 2021
51fcc1a
Merge branch 'migrationdocsphaseone' of https://github.com/StephenBon…
StephenBonikowsky Jul 2, 2021
9e68971
Update breaking-changes.md
adegeo Jul 2, 2021
c70143d
Update versioning....md
adegeo Jul 2, 2021
ea2e1ac
Upgrade porting-approaches.md
adegeo Jul 2, 2021
1d37523
Upgrade premigration-needed-changes.md
adegeo Jul 2, 2021
de63b80
Upgrade project-structure.md
adegeo Jul 2, 2021
ceec08b
Upgrade unsupported-apis.md
adegeo Jul 2, 2021
6c82b4b
TOC naming changes
adegeo Jul 2, 2021
be12ba0
Merge pull request #3 from dotnet/adegeo-24630
StephenBonikowsky Jul 2, 2021
0f0c642
Update docs/core/porting/project-structure.md
StephenBonikowsky Jul 2, 2021
1145aa0
Update docs/core/porting/project-structure.md
StephenBonikowsky Jul 2, 2021
bea5356
Update porting-approaches.md
adegeo Jul 2, 2021
4ce59fd
Update premigration-needed-changes.md
adegeo Jul 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/core/porting/breaking-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Breaking changes can affect porting your app
description: Breaking changes can occur when porting your code from .NET framework to .NET and between versions of .NET. This article describes categories of breaking changes, ways a change can affect compatibility and how to find breaking changes.
author: StephenBonikowsky
ms.author: stebon
ms.date: 06/14/2021
---
# Breaking changes may occur when porting code

Changes that affect compatibility, otherwise known as breaking changes, will occur between versions of .NET. Changes are impactful when porting from .NET Framework to .NET because of certain technologies not being available. Also, you can come across breaking changes simply because .NET is a cross-platform technology and .NET Framework isn't.

Microsoft strives to maintain a high level of compatibility between .NET versions, so while breaking changes do occur, they're carefully considered.

Before upgrading major versions, check the breaking changes documentation for changes that might affect you.

## Categories of breaking changes

There are several types of breaking changes...

- modifications to the public contract
- behavioral changes
- Platform support
- Internal implementation changes
- Code changes

For more information about what is allowed or disallowed, see [Changes that affect compatibility](../compatibility/index.md)

## Types of compatibility

Compatibility refers to the ability to compile or run code on a .NET implementation other than the one with which the code was originally developed.

There are six different ways a change can affect compatibility...

- Behavioral changes
- Binary compatibility
- Source compatibility
- Design-time compatibility
- Backwards compatibility
- Forward compatibility

For more information, see [How code changes can affect compatibility](../compatibility/categories.md)

## Find breaking changes

Changes that affect compatibility are documented and should be reviewed before porting from .NET Framework to .NET or when upgrading to a newer version of .NET.

For more information, see [Breaking changes reference overview](../compatibility/breaking-changes.md)
98 changes: 98 additions & 0 deletions docs/core/porting/porting-approaches.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: Porting approaches
description: Create a porting plan that best reflects your project and context.
author: StephenBonikowsky
ms.author: stebon
ms.date: 06/10/2021
---
# Create a porting plan

Before you jump straight into the code, take the time to go through the recommended pre-migration steps. This article gives you insight into the kinds of issues you may come across, and helps you decide on an approach that makes the most sense.

## Port your code

Make sure that you follow the [prerequisites to porting code](premigration-needed-changes.md) before you continue any further. Be ready to decide on the best approach for you and begin porting code.

### Deal primarily with the compiler

This approach works well for small projects or projects that don't use many .NET Framework APIs. The approach is simple:

01. Optionally, run **ApiPort** on your project. If you run **ApiPort**, gain knowledge from the report on issues you'll need to address.
01. Copy all of your code over into a new .NET project.
01. While referring to the portability report (if generated), solve compiler errors until the project fully compiles.

Although it's unstructured, this code-focused approach often resolves issues quickly. A project that contains only data models might be an ideal candidate for this approach.

### Stay on the .NET Framework until portability issues are resolved

This approach might be the best if you prefer to have code that compiles during the entire process. The approach is as follows:

01. Run **ApiPort** on a project.
01. Address issues by using different APIs that are portable.
01. Take note of any areas where you're prevented from using a direct alternative.
01. Repeat the prior steps for all projects you're porting until you're confident each is ready to be copied over into a new .NET project.
01. Copy the code into a new .NET project.
01. Work out any issues where you noted that a direct alternative doesn't exist.

This careful approach is more structured than simply working out compiler errors, but it's still relatively code-focused and has the benefit of always having code that compiles. The way you resolve certain issues that couldn't be addressed by just using another API varies greatly. You may find that you need to develop a more comprehensive plan for certain projects, which is covered in the next approach.

### Develop a comprehensive plan of attack

This approach might be best for larger and more complex projects, where restructuring code or completely rewriting certain areas of code might be necessary to support .NET. The approach is as follows:

01. Run **ApiPort** on a project.
01. Understand where each non-portable type is used and how that affects overall portability.

- Understand the nature of those types. Are they small in number but used frequently? Are they large in number but used infrequently? Is their use concentrated, or is it spread throughout your code?
- Is it easy to isolate code that isn't portable so that you can deal with it more effectively?
- Do you need to refactor your code?
- For those types that aren't portable, are there alternative APIs that accomplish the same task? For example, if you're using the <xref:System.Net.WebClient> class, use the <xref:System.Net.Http.HttpClient> class instead.
- Are there different portable APIs available to accomplish a task, even if it's not a drop-in replacement? For example, if you're using <xref:System.Xml.Schema.XmlSchema> to parse XML but don't require XML schema discovery, you could use <xref:System.Xml.Linq> APIs and implement parsing yourself instead of relying on an API.

01. If you have assemblies that are difficult to port, is it worth leaving them on .NET Framework for now? Here are some things to consider:

- You may have some functionality in your library that's incompatible with .NET because it relies too heavily on .NET Framework or Windows-specific functionality. Is it worth leaving that functionality behind for now and releasing a temporary .NET version of your library with fewer features until resources are available to port the features?
- Would a refactor help?

01. Is it reasonable to write your own implementation of an unavailable .NET Framework API?

You could consider copying, modifying, and using code from the [.NET Framework reference source](https://github.com/Microsoft/referencesource). The reference source code is licensed under the [MIT License](https://github.com/Microsoft/referencesource/blob/master/LICENSE.txt), so you have significant freedom to use the source as a basis for your own code. Just be sure to properly attribute Microsoft in your code.

01. Repeat this process as needed for different projects.

The analysis phase could take some time depending on the size of your codebase. Spending time in this phase to thoroughly understand the scope of changes needed and to develop a plan usually saves you time in the end, particularly if you have a complex codebase.

Your plan could involve making significant changes to your codebase while still targeting .NET Framework 4.7.2. This is a more structured version of the previous approach. How you go about executing your plan is dependent on your codebase.

### Mixed approach

It's likely that you'll mix the above approaches on a per-project basis. Do what makes the most sense to you and for your codebase.

## Port your tests

The best way to make sure everything works when you've ported your code is to test your code as you port it to .NET. To do this, you'll need to use a testing framework that builds and runs tests for .NET. Currently, you have three options:

- [xUnit](https://xunit.net/)
- [Getting Started](https://xunit.net/docs/getting-started/netcore/cmdline)
- [Tool to convert an MSTest project to xUnit](https://github.com/dotnet/codeformatter/tree/main/src/XUnitConverter)
- [NUnit](https://nunit.org/)
- [Getting Started](https://github.com/nunit/docs/wiki/Installation)
- [Blog post about migrating from MSTest to NUnit](https://www.florian-rappl.de/News/Page/275/convert-mstest-to-nunit)
- [MSTest](/visualstudio/test/unit-test-basics)

## Recommended approach

Ultimately, the porting effort depends heavily on how your .NET Framework code is structured. A good way to port your code is to begin with the *base* of your library, which is the foundational components of your code. This might be data models or some other foundational classes and methods that everything else uses directly or indirectly.

01. Port the test project that tests the layer of your library that you're currently porting.
01. Copy over the base of your library into a new .NET project and select the version of .NET Standard you wish to support.
01. Make any changes needed to get the code to compile. Much of this may require adding NuGet package dependencies to your *csproj* file.
01. Run the tests and make any needed adjustments.
01. Pick the next layer of code to port over and repeat the prior steps.

If you start with the base of your library and move outward from the base and test each layer as needed, porting is a systematic process where problems are isolated to one layer of code at a time.

## Next steps

- [Overview of the .NET Upgrade Assistant](upgrade-assistant-overview.md)
- [Organize your project to support both .NET Framework and .NET Core](project-structure.md)
42 changes: 42 additions & 0 deletions docs/core/porting/premigration-needed-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: Prerequisites to port from .NET Framework
description: Before porting your code from .NET Framework to .NET, you must use the correct developer environment and update your project files as required.
author: StephenBonikowsky
ms.author: stebon
ms.date: 06/10/2021
---
# Prerequisites to porting code

Make the needed changes to build and run a .NET application before beginning the work to port your code. These changes can be done while still building and running a .NET Framework application.

## Upgrade to required tooling

Upgrade to a version of MSBuild/Visual Studio that supports the version of .NET you will be targeting. See [Versioning relationship between the .NET SDK, MSBuild and VS](versioning-sdk-msbuild-vs.md) for more info.

## Update .NET Framework target version

We recommended that you target your .NET Framework app to version 4.7.2 or higher. This ensures the availability of the latest API alternatives for cases where .NET Standard doesn't support existing APIs.

For each of the projects you wish to port, do the following in Visual Studio:

01. Right-click on the project and select **Properties**.
01. In the **Target Framework** dropdown, select **.NET Framework 4.7.2**.
01. Recompile the project.

Because your projects now target .NET Framework 4.7.2, use that version of the .NET Framework as your base for porting code.

## Change to PackageReference format

Convert all references to the [PackageReference](/nuget/consume-packages/package-references-in-project-files) format.

## Convert to SDK style project format

Convert your projects to the [SDK-style format](../project-sdk/overview.md).

## Update dependencies

Update dependencies to their latest version available, and to .NET Standard version where possible.

## Next steps

- [Create a porting plan](porting-approaches.md)
61 changes: 30 additions & 31 deletions docs/core/porting/project-structure.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,61 @@
---
title: Organize projects for .NET Framework and .NET Core
description: Help for project owners who want to compile their solution against .NET Framework and .NET Core side-by-side.
title: Organize projects for .NET Framework and .NET
description: Help for project owners who want to compile their solution against .NET Framework and .NET side by side.
author: conniey
ms.date: 12/07/2018
ms.date: 07/02/2021
---
# Organize your project to support both .NET Framework and .NET Core
# Organize your project to support both .NET Framework and .NET

You can create a solution that compiles for both .NET Framework and .NET Core side-by-side. This article covers several project-organization options to help you achieve this goal. Here are some typical scenarios to consider when you're deciding how to set up your project layout with .NET Core. The list may not cover everything you want; prioritize based on your project's needs.
You can create a solution that compiles for both .NET Framework and .NET side by side. This article covers several project-organization options to help you achieve this goal. Here are some typical scenarios to consider when you're deciding how to set up your project layout with .NET. The list may not cover everything you want.

- [**Combine existing projects and .NET Core projects into single projects**](#replace-existing-projects-with-a-multi-targeted-net-core-project)
- [Combine existing projects and .NET projects into a single project](#replace-existing-projects-with-a-multi-targeted-net-project)

**Benefits**:

*What this is good for:*
- Simplifies your build process by compiling a single project rather than multiple projects that each target a different .NET Framework version or platform.
- Simplifies source file management for multi-targeted projects because you must manage a single project file. When adding or removing source files, the alternatives require you to manually sync these with your other projects.
- Simplifies source file management for multi-targeted projects because you must manage a single project file. When adding or removing source files, the alternatives require you to manually sync these files with your other projects.
- Easily generate a NuGet package for consumption.
- Allows you to write code for a specific .NET Framework version in your libraries through the use of compiler directives.
- Allows you to write code for a specific .NET Framework version by using compiler directives.

*Unsupported scenarios:*
- Requires developers to use Visual Studio 2017 or a later version to open existing projects. To support older versions of Visual Studio, [keeping your project files in different folders](#support-vs) is a better option.
**Drawback**:

- <a name="support-vs"></a>[**Keep existing projects and new .NET Core projects separate**](#keep-existing-projects-and-create-a-net-core-project)
- Requires developers to use Visual Studio 2019 or a later version to open existing projects. To support older versions of Visual Studio, [keeping your project files in different folders](#support-vs) is a better option.

*What this is good for:*
- Supports development on existing projects for developers and contributors who may not have Visual Studio 2017 or a later version.
- Decreases the possibility of creating new bugs in existing projects because no code churn is required in those projects.
- <a name="support-vs"></a>[Keep all projects separate](#keep-existing-projects-and-create-a-net-project)

## Example
**Benefits**:

Consider the repository below:
- Supports development on existing projects for developers and contributors who may not have Visual Studio 2019 or a later version.
- Lowers the possibility of creating new bugs in existing projects because no code churn is required in those projects.

![Existing project](./media/project-structure/existing-project-structure.png)
Consider [this example GitHub repository](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library/). The figure below shows how this repository is laid out:

[**Source Code**](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library/)
:::image type="content" source="media/project-structure/existing-project-structure.png" alt-text="Existing project structure diagram":::

The following describes several ways to add support for .NET Core for this repository depending on the constraints and complexity of the existing projects.
The following sections describe several ways to add support for .NET based on the example repository.

## Replace existing projects with a multi-targeted .NET Core project
## Replace existing projects with a multi-targeted .NET project

Reorganize the repository so that any existing *\*.csproj* files are removed and a single *\*.csproj* file is created that targets multiple frameworks. This is a great option, because a single project is able to compile for different frameworks. It also has the power to handle different compilation options and dependencies per targeted framework.
Reorganize the repository so that any existing *\*.csproj* files are removed and a single *\*.csproj* file is created that targets multiple frameworks. This is a great option, because a single project can compile for different frameworks. It also has the power to handle different compilation options and dependencies per targeted framework.

![Create a csproj that targets multiple frameworks](./media/project-structure/multi-targeted-project.png)
:::image type="content" source="media/project-structure/multi-targeted-project.png" alt-text="project that targets multiple frameworks diagram":::

[**Source Code**](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library-csproj/)
For example code, see [GitHub](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library-csproj/).

Changes to note are:

- Replacement of *packages.config* and *\*.csproj* with a new [.NET Core *\*.csproj*](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library-csproj/src/Car/Car.csproj). NuGet packages are specified with `<PackageReference> ItemGroup`.
- Replacement of *packages.config* and *\*.csproj* with a new [.NET *\*.csproj*](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library-csproj/src/Car/Car.csproj). NuGet packages are specified with `<PackageReference> ItemGroup`.

## Keep existing projects and create a .NET Core project
## Keep existing projects and create a .NET project

If there are existing projects that target older frameworks, you may want to leave these projects untouched and use a .NET Core project to target future frameworks.
If there are existing projects that target older frameworks, you may want to leave these projects untouched and use a .NET project to target future frameworks.

![.NET Core project with existing project in different folder](./media/project-structure/separate-projects-same-source.png)
:::image type="content" source="media/project-structure/separate-projects-same-source.png" alt-text=".NET project with existing projects in a different folder diagram":::

[**Source Code**](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library-csproj-keep-existing/)
For example code, see [GitHub](https://github.com/dotnet/samples/tree/main/framework/libraries/migrate-library-csproj-keep-existing/).

The .NET Core and existing projects are kept in separate folders. Keeping projects in separate folders avoids forcing you to have Visual Studio 2017 or later versions. You can create a separate solution that only opens the old projects.
The .NET and existing projects are kept in separate folders. Keeping projects in separate folders avoids forcing you to have Visual Studio 2019 or later versions. You can create a separate solution that only opens the old projects.

## See also

- [.NET Core porting documentation](index.md)
- [.NET porting documentation](index.md)
Loading