Начиная с .NET 5 для работы с Windows Forms или WPF требуется указать Target Framework Moniker
https://docs.microsoft.com/en-us/dotnet/standard/frameworks
Если программа изначально нацелена на работу с ними, то проблем нет.
Однако если мы хотим создать консольное приложение и где-то в зависимостях используется тип из System.Windows.Forms, и даже если сам класс этот не используется, нужно все проекты переводить на -windows TFM.
Результат печален, получаем лишние 60МБ, которые просто не нужны.
Решение: Вручную прописать зависимости фреймворка.
Результат: 18МБ против 81МБ без изменения кода.
Никаких хаков, всё документировано:
https://github.com/NuGet/Home/wiki/%5BSpec%5D-FrameworkReference-in-NuGet
https://github.com/dotnet/designs/blob/main/accepted/2019/targeting-packs-and-runtime-packs.md
Код:
Зависимость
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ClassLibrary2
{
public class Class1
{
void F()
{
var f = new Form();
f.Show();
}
}
}
Наша программа
class A
{
public static void Main()
{
}
}
До:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>
После:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.NETCore.App" PrivateAssets="all" />
<FrameworkReference Include="Microsoft.WindowsDesktop.App" PrivateAssets="all" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.NETCore.App" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>
Посмотреть вживую:
http://files.rsdn.org/16901/winforms-no-tfm.zip