dotnet / project-system

The .NET Project System for Visual Studio
MIT License
969 stars 387 forks source link

Dependencies node fails to handle custom target frameworks #2618

Closed sharwell closed 1 year ago

sharwell commented 7 years ago

Steps to reproduce

  1. Create a new project
  2. Set the target frameworks to Xyz1.0
  3. Explicitly set the TargetFrameworkIdentifier, TargetFrameworkVersion, and TargetFrameworkProfile properties
  4. Open the project in Visual Studio
<PropertyGroup>
  <TargetFrameworks>Xyz1.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
  <TargetFrameworkIdentifier>.NETCustom</TargetFrameworkIdentifier>
  <TargetFrameworkVersion>v42.42</TargetFrameworkVersion>
  <TargetFrameworkProfile />
</PropertyGroup>

Expected results

Solution Explorer shows a dependencies node based on the explicitly set framework identifier, version, and profile. In the above case, this would be .NETCustom 42.42.

Actual results

Solution Explorer shows Unsupported 0.0.

abpiskunov commented 7 years ago

This scenario is kind of limited. If you specify custom TFMX - how does project system/nuget know if TFMX can support a net46 etc? Dependencies logic needs this info in several places to decide if a warning icon should be displayed for project to project references for example...

sharwell commented 7 years ago

:memo: This is related to #1938, though the problem can manifest in other scenarios as well. In my case, I believe I was trying to work around #2617 when I first hit this.

srivatsn commented 7 years ago

The project system should just use the full target framework moniker for such comparisons. The simplest thing to do here might be to just show the TF as-is without mapping it to anything. That way if the user has a testingfornetstandard1.0 TF as in my example in #1938 then that value shows up in the tree. That node can have a TargetFrameworkMoniker property (in the property grid) which can show what it maps to by simply evaluating the TargetFrameworkMoniker

davkean commented 7 years ago

Yes, this should work and how this was designed. In particular:

DO NOT parse or attempt to reason about the values of properties that make up the dimensions for a project configuration; $(Configuration), $(Platform) and $(TargetFramework), and their plural counterparts; $(Configurations), $(Platforms) and $(TargetFrameworks). These properties are user "aliases" and should only be used for conditions, display and grouping purposes. Instead, the project system should be using their canonical equivalents; $(PlatformTarget) instead of $(Platform), and $(TargetFrameworkMoniker) instead of $(TargetFramework).

drewnoakes commented 1 year ago

Another test case for this:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>foo1.0;bar2.0</TargetFrameworks>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)' == 'foo1.0'">
    <TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>7.0</TargetFrameworkVersion>
    <TargetFrameworkProfile />
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)' == 'bar2.0'">
    <TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>2.0</TargetFrameworkVersion>
    <TargetFrameworkProfile />
  </PropertyGroup>

</Project>

Screenshot from the dependencies tree rewrite:

image