Skip to content

Update .NET Core porting document to VS2017 #1768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file modified docs/core/porting/media/project-structure/project.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
100 changes: 31 additions & 69 deletions docs/core/porting/project-structure.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
---
title: Organizing Your Project to Support .NET Framework and .NET Core
description: Organizing Your Project to Support .NET Framework and .NET Core
keywords: .NET, .NET Core
title: Organizing your project to support .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.
keywords: .NET, .NET Core, .NET Framework, project layout, multiple frameworks
author: conniey
ms.author: mairaw
ms.date: 07/18/2016
ms.date: 04/06/2017
ms.topic: article
ms.prod: .net-core
ms.devlang: dotnet
ms.assetid: 3af62252-1dfa-4336-8d2f-5cfdb57d7724
---

# Organizing Your Project to Support .NET Framework and .NET Core
# Organizing your project to support .NET Framework and .NET Core

> [!WARNING]
> This topic hasn't been updated to the latest version of the tooling yet.
This article helps project owners who want to compile their solution against .NET Framework and .NET Core side-by-side. It provides several options to organize projects to help developers achieve this goal. The following list provides some typical scenarios to consider when you're deciding how to setup your project layout with .NET Core. The list may not cover everything you want; prioritize based on your project's needs.

This article is to help project owners who want to compile their solution against .NET Framework and .NET Core side-by-side. It provides several options to organize projects to help developers achieve this goal. Here are some typical scenarios to consider when you are deciding how to setup your project layout with .NET Core. They may not cover everything you want; prioritize based on your project's needs.
* [**Combine existing projects and .NET Core projects into single projects**][option-csproj]

* [**Combine existing projects and .NET Core projects into single projects**][option-xproj]

*What this is good for:*
* Simplifying your build process by compiling a single project rather than compiling multiple projects, each targeting a different .NET Framework version or platform.
* Simplifying source file management for multi-targeted projects because you have to manage a single project file. When adding/removing source files, the alternatives require you to manually sync these with your other projects.
* Simplifying source file management for multi-targeted projects because you must manage a single project file. When adding/removing source files, the alternatives require you to manually sync these with your other projects.
* Easily generating 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.

*Unsupported scenarios:*
* Does not allow developers without Visual Studio 2015 to open existing projects. To support older versions of Visual Studio, [keeping your project files in different folders](#support-vs) is a better option.
* Does not allow you to share your .NET Core library across different project types in the same solution file. To support this, [creating a Portable Class Library](#support-pcl) is a better option.
* Does not allow for project build or load modifications that are supported by MSBuild Targets and Tasks. To support this, [creating a Portable Class Library](#support-pcl) is a better option.

* <a name="support-vs"></a>[**Keep existing projects and new .NET Core projects separate**][option-xproj-folder]

*What this is good for:*
* Continuing to support development on existing projects without having to upgrade for developers/contributors who may not have Visual Studio 2015.
* Decreasing the possibility in creating new bugs in existing projects because no code churn is required in those projects.
*Unsupported scenarios:*
* Requires developers to use Visual Studio 2017 to open existing projects. To support older versions of Visual Studio, [keeping your project files in different folders](#support-vs) is a better option.

* <a name="support-pcl"></a>[**Keep existing projects and create Portable Class Libraries (PCLs) targeting .NET Core**][option-pcl]
* <a name="support-vs"></a>[**Keep existing projects and new .NET Core projects separate**][option-csproj-folder]

*What this is good for:*
* Referencing your .NET Core libraries in desktop and/or web projects targeting the full .NET Framework in the same solution.
* Supporting modifications in the project build or load process. These modifications could be the inclusion of MSBuild Tasks and Targets in your `*.csproj` file.

*Unsupported scenarios:*
* Does not allow you to write code for a specific .NET Framework version because the [predefined preprocessor symbols][how-to-multitarget] are not supported.
* Continuing to support development on existing projects without having to upgrade for developers/contributors who may not have Visual Studio 2017.
* Decreasing the possibility of creating new bugs in existing projects because no code churn is required in those projects.

## Example

Expand All @@ -54,69 +40,45 @@ Consider the repository below:

[**Source Code**][example-initial-project-code]

There are several different ways to add support for .NET Core for this repository depending on the constraints and complexity of existing projects which are described below.
The following describes several ways to add support for .NET Core for this repository depending on the constraints and complexity of the existing projects.

## Replace Existing Projects with a Multi-targeted .NET Core Project (xproj)
## Replace existing projects with a multi-targeted .NET Core project

The repository can be reorganized so that any existing `*.csproj` files are removed and a single `*.xproj` 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, dependencies, etc. 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 is able to compile for different frameworks. It also has the power to handle different compilation options and dependencies per targeted framework.

![Create an xproj that targets multiple frameworks][example-xproj]
![Create an csproj that targets multiple frameworks][example-csproj]

[**Source Code**][example-xproj-code]
[**Source Code**][example-csproj-code]

Changes to note are:
* Addition of `global.json`
* Replacement of `packages.config` and `*.csproj` with `project.json` and `*.xproj`
* Changes in the [Car's project.json][example-xproj-projectjson] and its [test project][example-xproj-projectjson-test] to support building for the existing .NET Framework as well as others

## Create a Portable Class Library (PCL) to target .NET Core

If existing projects contain complex build operations or properties in their `*.csproj` file, it may be easier to create a PCL.
* Replacement of *packages.config* and *\*.csproj* with a new [.NET Core *\*.csproj*][example-csproj-netcore]. NuGet packages are specified with `<PackageReference> ItemGroup`.

![][example-pcl]

[**Source Code**][example-pcl-code]

Changes to note are:
* Renaming `project.json` to `{project-name}.project.json`
* This prevents potential conflict in Visual Studio when trying to restore packages for the libraries in the same directory. For more information, see the [NuGet FAQ](https://docs.nuget.org/consume/nuget-faq#working-with-packages) under "_I have multiple projects in the same folder, how can I use separate packages.config or project.json files for each project?_".
* **Alternative**: Create the PCL in another folder and reference the original source code to avoid this issue. Placing the PCL in another folder has an added benefit that users who do not have Visual Studio 2015 can still work on the older projects without loading the new solution.
* To target .NET Standard after creating the PCL, in Visual Studio, open the **Project's Properties**. Under the **Targets** section, click on the link **"Target .NET Platform Standard"**. This change can be reversed by repeating the same steps.

## Keep Existing Projects and Create a .NET Core Project
## Keep existing projects and create a .NET Core 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.

![.NET Core project with existing PCL in different folder][example-xproj-different-folder]
![.NET Core project with existing project in different folder][example-csproj-different-folder]

[**Source Code**][example-xproj-different-code]
[**Source Code**][example-csproj-different-code]

Changes to note are:
* The .NET Core and existing projects are kept in separate folders.
* This avoids the package restore issue that was mentioned above due to multiple project.json/package.config files being in the same folder.
* Keeping projects in separate folders avoids forcing you to have Visual Studio 2015 (due to project.json). You can create a separate solution that only opens the old projects.
* Keeping projects in separate folders avoids forcing you to have Visual Studio 2017. You can create a separate solution that only opens the old projects.

## See Also

Please see [.NET Core porting documentation][porting-doc] for more guidance on moving to project.json and xproj.
Please see the [.NET Core porting documentation][porting-doc] for more guidance on migrating to .NET Core.

[porting-doc]: index.md
[example-initial-project]: media/project-structure/project.png "Existing project"
[example-initial-project-code]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library/

[example-xproj]: media/project-structure/project.xproj.png "Create an xproj that targets multiple frameworks"
[example-xproj-code]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-xproj/
[example-xproj-projectjson]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-xproj/src/Car/project.json
[example-xproj-projectjson-test]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-xproj/tests/Car.Tests/project.json

[example-xproj-different-folder]: media/project-structure/project.xproj.different.png ".NET Core project with existing PCL in different folder"
[example-xproj-different-code]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-xproj-keep-csproj/

[example-pcl]: media/project-structure/project.pcl.png "PCL Targeting .NET Core"
[example-pcl-code]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-pcl
[example-csproj]: media/project-structure/project.csproj.png "Create an csproj that targets multiple frameworks"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with this static resource format. @mairaw How does this work? Is this valid?

I've been using ...

![alt text](./media/folder/image.png)

[example-csproj-code]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-csproj/
[example-csproj-netcore]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-csproj/src/Car/Car.csproj

[option-xproj]: #replace-existing-projects-with-a-multi-targeted-net-core-project-xproj
[option-pcl]: #create-a-portable-class-library-pcl-to-target-net-core
[option-xproj-folder]: #keep-existing-projects-and-create-a-net-core-project
[example-csproj-different-folder]: media/project-structure/project.csproj.different.png ".NET Core project with existing PCL in different folder"
[example-csproj-different-code]: https://github.com/dotnet/docs/tree/master/samples/framework/libraries/migrate-library-csproj-keep-existing/

[how-to-multitarget]: ../tutorials/libraries.md#how-to-multitarget
[option-csproj]: #replace-existing-projects-with-a-multi-targeted-net-core-project
[option-csproj-folder]: #keep-existing-projects-and-create-a-net-core-project
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7CB5EAA7-6A21-48DD-995E-8C8BEBBEEC10}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{4003AC6C-E0EA-4A4B-BA4A-35BEAE8EDAC3}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Car", "src\Car\Car.xproj", "{5F4E989B-BC5C-4925-A7A7-9DF3E3EDA279}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Car", "src\Car\Car.csproj", "{5F4E989B-BC5C-4925-A7A7-9DF3E3EDA279}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Car.Tests", "tests\Car.Tests\Car.Tests.xproj", "{D1CA7CE9-E3EF-43D6-BFE7-7E67B1752517}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Car.Tests", "tests\Car.Tests\Car.Tests.csproj", "{D1CA7CE9-E3EF-43D6-BFE7-7E67B1752517}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Car.Net45", "src\Car.Net45\Car.Net45.csproj", "{23BE49E4-6308-4BF0-BD3B-852B5A25EA19}"
EndProject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
</packages>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Car.Net45\Car.Net45.csproj">
<Project>{23be49e4-6308-4bf0-bd3b-852b5a25ea19}</Project>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Car\Car.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7CB5EAA7-6A21-48DD-995E-8C8BEBBEEC10}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{4003AC6C-E0EA-4A4B-BA4A-35BEAE8EDAC3}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Car", "src\Car\Car.xproj", "{5F4E989B-BC5C-4925-A7A7-9DF3E3EDA279}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Car", "src\Car\Car.csproj", "{5F4E989B-BC5C-4925-A7A7-9DF3E3EDA279}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Car.Tests", "tests\Car.Tests\Car.Tests.xproj", "{D1CA7CE9-E3EF-43D6-BFE7-7E67B1752517}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Car.Tests", "tests\Car.Tests\Car.Tests.csproj", "{D1CA7CE9-E3EF-43D6-BFE7-7E67B1752517}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net452;net461;netstandard1.6</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.6' ">
<Reference Include="System.Collections.Concurrent" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Car\Car.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>
Loading