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

Consume C# nuget from C++/Cx with additional C# dependencies #6146

Closed
DominikMe opened this issue Nov 6, 2017 · 3 comments
Closed

Consume C# nuget from C++/Cx with additional C# dependencies #6146

DominikMe opened this issue Nov 6, 2017 · 3 comments

Comments

@DominikMe
Copy link

Problem statement

It is hard to pack a C# Windows Runtime Component that has dependencies to other CLR nuget packages so that it can be consumed from a C++/Cx Universal Windows App.

Notice that this is not the typical "consume native from managed" problem but the opposite direction: an existing C++ app that needs to consume XAML controls and libraries written in C#.

The question is how to do this properly, a minimal working solution is attached. However, my approach does not feel quite right.

Details about Problem

Setup:

  1. A C# Universal Windows Runtime Component project with a XAML control that has dependencies to other managed nugets. In this example, to Newtonsoft.Json.

  2. A C++/Cx Universal Windows App that needs to consume the C# XAML control. The C++ project is packages.config based.

In a perfect world, declaring dependencies in the RuntimeComponent's nuspec file would lead to restoring these packages. However, nuget restore fails because it cannot install C# packages into a C++ project.

Workaround:

To make this work, I included all dependencies directly. This is tricky because it includes transitive dependencies, such as a package C in a dependency chain A -> B -> C.

After lots of reading and experimenting I added <CopyNugetImplementations>true</CopyNugetImplementations> to my RuntimeComponent's csproj which will copy all assemblies that the project depends on to the build output folder. Then in my manually crafted nuspec, I copied these additional DLLs to my package with the <file> attribute. In the targets file these dependencies are then added to the consuming project with

<None Include="$(MSBuildThisFileDirectory)..\..\ref\*.dll">
    <DeploymentContent>true</DeploymentContent>
</None>

Problems with the workaround:

This solution works but has inherent issues.

Finding which DLLs need to be copied is very tedious:

  • Either include all DLLs. install the package to the C++ app, try to build and see which assemblies are rejected due to duplication
  • Or include DLLs one by one, install the package, build and run the C++ app and make note of LoadAssembly runtime errors, repeat.

In the attached minimal example, I ended up having to include Newtonsoft.Json and also even System DLLs.

<file src="bin\Release\Newtonsoft.Json.dll" target="ref" />
<file src="bin\Release\System.ComponentModel.TypeConverter.dll" target="ref" />
<file src="bin\Release\System.Runtime.Serialization.Formatters.dll" target="ref" />

What is the recommended approach to redistribute CLR nuget dependencies and their transitive dependencies with a Windows Runtime Component, so that it can be consumed from a C++ UWP project?


NuGet product used (NuGet.exe | VS UI | Package Manager Console | dotnet.exe): NuGet.exe

NuGet version (x.x.x.xxx): 4.3.0.4406

VS version (if appropriate): 15.4.2

OS version: win10 v1703 15063.674

Sample Project

UwpInteropPackaging_Example.zip

@zhili1208
Copy link
Contributor

@emgarten looks like we don't have a compete support for this scenario, do you know any better way to make this work?

@emgarten
Copy link
Member

emgarten commented Nov 10, 2017

The issue tracking support for C++ apps consuming managed assemblies is here: #5292 Please up vote and comment there.

I appreciate the detailed the write up of the issue, but at this time UWP is only using packages.config, which does not support the ref/ folder. We would like to tackle this problem directly instead of providing workarounds for the currently broken scenario.

@timg-mlbam
Copy link

I'm running into similar problems when trying to consume WinRT components in UWP JavaScript apps. (where WinRT component is written in C# but has non-WinRT C# internal dependencies like Json.NET). A solution to this would be great!

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

No branches or pull requests

4 participants