Sdk: Consider making FrameworkReferences implicit in WPF and Web SDKs

Created on 5 Oct 2018  Â·  10Comments  Â·  Source: dotnet/sdk

In .NET Core 3.0, a WPF project will import the WPF SDK in its project element (<Project Sdk="Microsoft.NET.Sdk.Wpf">​), and will also have a FrameworkReference to Microsoft.DesktopUI (<FrameworkReference Include="Microsoft.DesktopUI"/>​). Similarly, ASP.NET Core projects will use the Microsoft.NET.Sdk.Web SDK, and will have a FrameworkReference to Microsoft.AspNetCore.

Having to specify both the Sdk and the FrameworkReference seems redundant. They do serve separate purposes: the FrameworkReference allows you to use the APIs in the shared framework, while the Sdk import brings in the build logic (for example, razor or xaml compilation, or default globs for the project type).

We should consider having WPF and Web SDKs by default include an implicit FrameworkReference to the corresponding shared framework, and removing the FrameworkReferences from the project templates.

Most helpful comment

One advantage of an implicit FrameworkReference is that it could make it easier to multi-target a WPF project. It would be an error to specify a FrameworkReference if targeting .NET Framework, so you'd have to add a condition on the FrameworkReference item. However, if the FrameworkReference was implicit in the SDK, and the SDK also implicitly referenced a default set of WPF assemblies when targeting .NET Framework, then you could convert a .NET Core WPF project to multi-target to .NET Framework just by replacing <TargetFramework>netcoreapp3.0</TargetFramework> with <TargetFrameworks>netcoreapp3.0;net472</TargetFrameworks>

All 10 comments

One advantage of an implicit FrameworkReference is that it could make it easier to multi-target a WPF project. It would be an error to specify a FrameworkReference if targeting .NET Framework, so you'd have to add a condition on the FrameworkReference item. However, if the FrameworkReference was implicit in the SDK, and the SDK also implicitly referenced a default set of WPF assemblies when targeting .NET Framework, then you could convert a .NET Core WPF project to multi-target to .NET Framework just by replacing <TargetFramework>netcoreapp3.0</TargetFramework> with <TargetFrameworks>netcoreapp3.0;net472</TargetFrameworks>

I would go one step further and reference the default set of .NET Framework WinForms assemblies also. WPF support WinForms interop by default, and we'd need WinForms to be present for many of those scenarios.

The basic WPF assemblies I'd incldue are these:

`

<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="PresentationUI" />
<Reference Include="System.Windows.Controls.Ribbon" />
<Reference Include="UIAutomationClient" />
<Reference Include="UIAutomationClientSideProviders" />
<Reference Include="UIAutomationProvider" />
<Reference Include="UIAutomationTypes" />
<Reference Include="WindowsFormsIntegration" />

`

In addition to these, I'd add this:

<Reference Include="System.Windows.Forms" />

Besides these, having a few more .NET Framework assemblies referenced by default would be good to have. For e.g., System.Xml, System.Xaml.Linq, System.Core, System, System.Data. These seem to be already included today when multitargeting net472. Am I right?

@rladuca - thoughts on this?

On the different SDK and frameworks:
Since apps can specify multiple framework references, it is theoretically possible to create WPF app that hosts an ASP.NET Core server. If so, should I be able to use websdk tooling in addition to WPF tooling? Should I be able to layer both SDK's functionality in some way? Or do we want to write this off as "too hypothetical" or "please create a separate asp.net core project and use it as a project reference"

We definitely should make an attempt to include what was referenced in net472 for core. A developer working in desktop and writing code that uses the default WPF project references should just be able to flip to the SDK project and multi-target without any additional steps.

For reference, this is what I get from the basic template:

    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xaml"/>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />

So I would assume anything targeting netcoreapp3.0 would truck along those references equivalents to ensure developers have what is expected in a basic application.

@vatsan-madhavan I am not sure about the UIA assemblies though. I think most developers don't make use of the UIA assemblies directly. I am not sure how many people are actually writing AutomationPeers, even with custom controls.

@rladuca - I think having a complete list (of all possible WPF ref assemblies) is pretty cheap given there are no local copies etc when developing for the Desktop Framework. It also brings parity with the netcore scenario where all of it is available by default. Thoughts?

@vatsan-madhavan That makes sense. I can't really think of anything that would be negatively impacted by doing that.

@dsplaisted and maybe @vijayrkn: I would really appreciate an answer to my question from above
https://github.com/dotnet/cli/issues/10107#issuecomment-427519241

You should be able to add multiple (semicolon) seperated sdks in a project. But I dont know if the websdk and wpf sdk will work together.

@dasMulli The Web SDK and WPF SDK (which we're renaming to WindowsDesktop, and which will support both WPF and WinForms) will not work together. However, you could add a FrameworkReference to AspNetCore from a WPF project, or a FrameworkReference to WPF from a Web project. So you can use APIs from both frameworks in the same project, but not the build logic. If you need to use build logic from both app models, then you would need to factor your solution into separate projects, and have one reference the other.

This is now part of the latest build of the .NET Core SDK.

Was this page helpful?
0 / 5 - 0 ratings