Skip to content
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

System.Reactive reference pulls in all of WPF/SWF when TFM is net7.0-windows10.0.19041.0 or higher #9549

Closed
alexrp opened this issue Nov 27, 2022 · 5 comments · Fixed by #9749

Comments

@alexrp
Copy link

alexrp commented Nov 27, 2022

Consider this empty console app project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
    <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Avalonia.Direct2D1" Version="11.0.0-preview4" />
  </ItemGroup>
</Project>

If you do dotnet build and take a peek in bin/Debug/net7.0-windows10.0.19041.0/win10-x64, you'll notice something curious:

-rwxr-xr-x 1 alex 197609  8616056 Oct 19 16:40 PresentationCore.dll
-rwxr-xr-x 1 alex 197609    39088 Oct 19 16:40 PresentationFramework-SystemCore.dll
-rwxr-xr-x 1 alex 197609    34952 Oct 19 16:40 PresentationFramework-SystemData.dll
-rwxr-xr-x 1 alex 197609    34976 Oct 19 16:40 PresentationFramework-SystemDrawing.dll
-rwxr-xr-x 1 alex 197609    34960 Oct 19 16:40 PresentationFramework-SystemXml.dll
-rwxr-xr-x 1 alex 197609    30848 Oct 19 16:40 PresentationFramework-SystemXmlLinq.dll
-rwxr-xr-x 1 alex 197609   456864 Oct 19 16:40 PresentationFramework.Aero.dll
-rwxr-xr-x 1 alex 197609   460936 Oct 19 16:40 PresentationFramework.Aero2.dll
-rwxr-xr-x 1 alex 197609   239776 Oct 19 16:40 PresentationFramework.AeroLite.dll
-rwxr-xr-x 1 alex 197609   272544 Oct 19 16:40 PresentationFramework.Classic.dll
-rwxr-xr-x 1 alex 197609   682120 Oct 19 16:40 PresentationFramework.Luna.dll
-rwxr-xr-x 1 alex 197609   338080 Oct 19 16:40 PresentationFramework.Royale.dll
-rwxr-xr-x 1 alex 197609 16226464 Oct 19 16:40 PresentationFramework.dll
-rwxr-xr-x 1 alex 197609  1234088 Oct  7 05:04 PresentationNative_cor3.dll
-rwxr-xr-x 1 alex 197609  1288352 Oct 19 16:40 PresentationUI.dll
-rwxr-xr-x 1 alex 197609  1628288 Oct 19 16:40 ReachFramework.dll
... snip ...
-rwxr-xr-x 1 alex 197609    16512 Oct 19 03:24 System.Windows.Forms.Design.Editors.dll
-rwxr-xr-x 1 alex 197609  5335168 Oct 19 16:40 System.Windows.Forms.Design.dll
-rwxr-xr-x 1 alex 197609   960672 Oct 19 16:40 System.Windows.Forms.Primitives.dll
-rwxr-xr-x 1 alex 197609 13342848 Oct 19 16:40 System.Windows.Forms.dll
... snip ...
-rwxr-xr-x 1 alex 197609  1958000 Oct 19 06:34 wpfgfx_cor3.dll

Interestingly, changing TFM to net7.0-windows10.0.18362.0 (or lower) does not pull in WPF/SWF. The same is of course true when changing TFM to simply net7.0 or similar.

After some project.assets.json detective work, I figured out why:

https://github.com/dotnet/reactive/blob/85f1eb7c53e27cccdbeee3e0b044916168843fcc/Rx.NET/Source/src/System.Reactive/System.Reactive.csproj#L3-L21

As you can see, System.Reactive is multitargeted for net5.0 and net5.0-windows10.0.19041, with the latter TFM pulling in all of WPF/SWF. 🤦

In an ideal world, the fix here would be for System.Reactive to not assume that a windows TFM necessarily implies UseWPF=true and UseWindowsForms=true. But judging by this upstream issue, it doesn't seem like anything is likely to change here anytime soon, despite this assumption being obviously wrong. I'm not sure what, if anything, can be done on the Avalonia side.

@alexrp alexrp added the bug label Nov 27, 2022
@maxkatz6
Copy link
Member

maxkatz6 commented Nov 27, 2022

Yes, that's a problem with the System.Reactive, and we can't do much about it, unfortunately.

Developers can exclude some references from being copied to the output directory, something like <Reference Remove="PresentationFramework.dll" />, but that isn't really user friendly.

The best I can advice - make more noise in the System.Reactive repository, bringing up seriousness of this problem.

@maxkatz6 maxkatz6 removed the bug label Nov 27, 2022
@maxkatz6
Copy link
Member

Or we might actually try to remove this dependency at all. I will try and see this week. Hopefully, it won't affect any public API.

@maxkatz6
Copy link
Member

Well, we use ISubject in the public API unfortunately. It should be considered when bindings API cleanup is done: #9512.

@idg10
Copy link

idg10 commented Nov 21, 2023

Out of interest, did you ever try this:

  <PropertyGroup>
    <DisableTransitiveFrameworkReferences>true</DisableTransitiveFrameworkReferences>
  </PropertyGroup>

This disables the NuGet behaviour in which your project automatically acquires FrameworkReferences from the packages you use, and having tried it in this scenario, it prevents the WPF and Windows forms components being copied into the output folder.

I tested this on a net8.0-windows10.0.19041.0 using SDK 8.0.100 with <SelfContained>true</SelfContained> and you don't get all the WPF and Windows Forms components once you add that DisableTransitiveFrameworkReferences setting.

I know you've already abandoned Rx.NET, but our goal is to get Rx.NET into a state where you could reasonably come back to it if you chose to do so. We're trying to find a path forward for undoing the "great consolidation" in which the WPF and Windows Forms functionality got bundled into System.Reactive, causing this problem. Backcompat is a problem, but we now think there might be a path in which we deprecate the problematic types, with a view to eventually removing them entirely from System.Reactive.

If this DisableTransitiveFrameworkReferences would in fact work for Avalonia, that would mean it might be tolerable to leave these problematic types present but deprecated for a few more versions, eventually getting to a point where System.Reactive no longer has any -windows targets in it. (We can't just remove them immediately because that would cause all sorts of breakage for people who really are using these types.)

@maxkatz6
Copy link
Member

@idg10 it could work, yes. But as for now, there is very little need for System.Reactive in the framework itself. As we mostly have custom IObservable implementations, and only had to reimplement a small surface of observable extensions: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Base/Reactive/Observable.cs.
Not to mention, size improvements we got by avoiding additional dependencies. I am afraid, we don't see reasons for us to add System.Reactive as a dependency back. Except maybe only for user code, or part of our templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants