Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to resolve assembly reference issue without frameworkAssemblies

I'm trying to validate that Protocol Buffers is going to work with the new portable runtimes from the ASP.NET team and ideally most other modern environments. The 3.0.0-alpha4 build was created a while ago using profile259, so I would expect some changes to be required in some cases, but I thought I'd give it a try. I'm aware of Oren Novotny's post about targeting .NET Core, and expected to have to make some changes to the Google.Protobuf nuspec file, but the error I'm running into has me stumped.

DNX version: 1.0.0-rc1-update1

The scenario I'm currently trying to test is a console app targeting dnx451. I have a very simple sample app:

using Google.Protobuf.WellKnownTypes; using System;  public class Program {     public static void Main(string[] args)     {         Duration duration = new Duration { Seconds = 100, Nanos = 5555 };         Console.WriteLine(duration);     } } 

... and a tiny project.json:

{   "compilationOptions": { "emitEntryPoint": true },   "dependencies": { "Google.Protobuf": "3.0.0-alpha4" },    "frameworks": {     "dnx451": { }   } } 

Note that I'm not even using dnxcore* here - ironically, I got that to work without issues.

dnu restore works fine; dnx run fails with:

Error: c:\Users\Jon\Test\Projects\protobuf-coreclr\src\ProtobufTest\Program.cs(9,9): DNX,Version=v4.5.1 error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

The following changes result in the same error:

  • Explicitly adding a dependency to "System.Runtime": "4.0.0" in the dependencies section for the framework
  • Explicitly adding a dependency to "System.Runtime": "4.0.0-beta-23109" in the dependencies section for the framework, and likewise for 4.0.10-beta-*, 4.0.20-beta-* and 4.0.21-beta*.
  • Adding dependencies to System.Runtime within the NuGet package (locally) and rebuilding against that - project.lock.json was updated to include System.Runtime v4.0.0, but the same error occurred
  • Ditto including a lib\dotnet directory in the package, as well as the dependencies

Steps that did work (independently, and with no dependencies entries), but confuse me:

  • Changing the Console.WriteLine call to just Console.WriteLine("foo") (but no other changes)
  • Changing the type of the duration variable to object instead of Duration
  • Removing all hint of Protocol Buffers entirely, and instead using TimeSpan or similar
  • Adding the following to project.json in the dnx451 section:

    "frameworkAssemblies": {   "System.Runtime": "" } 

Ultimately, I don't want users to have to do this - at least, not for the sake of Protocol Buffers. I'm assuming this is something to do with how we're building Protocol Buffers, but as I don't understand the cause properly, it's hard to fix.

I expect that if I could work out a way of making a dependencies entry work, I could then add that dependency into Protocol Buffers itself, which would be fine - but as having a dependency on System.Runtime v4.0.0 in the project.lock file doesn't seem to help, I must be missing something :(

like image 543
Jon Skeet Avatar asked Dec 07 '15 14:12

Jon Skeet


People also ask

What is an assembly reference in C#?

Reference assemblies are usually distributed with the Software Development Kit (SDK) of a particular platform or library. Using a reference assembly enables developers to build programs that target a specific library version without having the full implementation assembly for that version.

How do I add assembly reference in net core project?

One method of adding references to your library is by typing it directly in the project. json file. As you can see that we have added some references under the dependencies section as shown in the following code. Let us now save this file and you will see that references are added to your library now.

What is assembly reference in asp net?

NET-based applications. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (. dll) files, and are the building blocks of . NET applications.


1 Answers

So if you squint and look at the project.json, it's basically a nuspec with a little bit of goop to describe what compilation options and sources are needed to build to project. Nuspecs today have 2 sections, frameworkAssemblies for "built in" stuff and dependencies for other nuget dependencies. It has the same meaning here. When you use something from "the framework", it needs to be specified in frameworkAssemblies vs being a nuget package dependency.

Now onto specifics:

When you use a PCL or .NET Core based library on .NET Framework, the references are to reference assemblies (sometimes called contract assemblies). Some examples of these are things like System.Runtime, System.Threading etc. When using MSBUILD based projects, there is a task that runs which basically automatically adds all of the System.* references to the C# compiler to avoid this mess. These assemblies are called facades on .NET Framework. The unfortunate part is that it adds ALL of them even if they aren't used. A dependency on System.Runtime is the trigger for this behavior (when running on .NET Framework based csproj files).

The reason adding a reference to the same package doesn't work is because the .NET Framework folder (net4*) for those contract assemblies (like System.Runtime), don't have any dlls in them. If you look at those folders, you'll see an empty _._ file. The reasoning for this is because when you declare a nuget package with a frameworkAssembly reference to System.Runtime, the msbuild project systems fails to install it (very complicated bug and design problem).

That probably made things fuzzier...

like image 127
davidfowl Avatar answered Oct 04 '22 11:10

davidfowl