59

Maybe I have a miss understanding of what ".NET Core Library" means, but when I try to add a .NET Core Library in a .NET 4.6 Assembly using Visual Studio 2015, I get the error:

A reference to '...' could not be added.

Did I understand something wrong?

This is what I configured in project.json of the .NET Core assembly

"frameworks": {
   "net451": { },
   "dotnet5.4": {
     "dependencies": {
     "Microsoft.CSharp": "4.0.1-beta-23516",
     "System.Collections": "4.0.11-beta-23516",
     "System.Linq": "4.0.1-beta-23516",
     "System.Runtime": "4.0.21-beta-23516",
     "System.Threading": "4.0.11-beta-23516"
  }
}
wonea
  • 4,783
  • 17
  • 86
  • 139
Roman L.
  • 869
  • 1
  • 8
  • 15
  • first, change `"net451"` to `"net46"` so that you use .NET 4.6. Second, make sure that the project you are adding the reference to, uses the same frameworks. MVC uses `dnx451` – GregoryHouseMD Nov 19 '15 at 17:32
  • I changed net451 to net46. Does not help. I have just created a new solution with a new empty NET Core library and a new empty "normal" .NET 4.6 class library. I still get the same error ... – Roman L. Nov 19 '15 at 17:36
  • I don't think that what you want to do is supported. Can't you migrate the other library as well? – GregoryHouseMD Nov 19 '15 at 18:18
  • I'm currently running across some issues with RC1, but in Beta8 I had this working by creating a nuget package and then managing that nuget package from the .net 4.6 project. Currently, I'm trying to find out what the difference between dotnet5.4 and dnxcore50 is. – Chad Carter Nov 19 '15 at 20:25
  • @Chad Carter - I'm also trying to figure the same thing out after upgrading to RC1 yesterday. According to https://github.com/aspnet/Announcements/issues/98, "Class Libraries" are supposed to use the net451 and dotnet5.4 monikers instead of the old dnx451/dnxcore50 so they updated the VS templates to reflect that. However, "applications" are still supposed to target dnx* monikers but that creates incompatibility between the application and the class library packages due to different framework targets. I don't understand what exactly Microsoft is expecting us to do here. – Aerendel Nov 20 '15 at 18:51
  • 1
    I have the same issue with .NET 4.6.1 as Main project and a .NET Core library (dotnet5.4) – Mohsen Afshin Feb 11 '16 at 07:27

5 Answers5

23

This can now be done with .Net Core RC2. Here is how:

  1. Ensure your .Net RC2 projects' project.json is configured to include the relevant .net framework. For example this section references .Net 4.51 which can be reference by any of the frameworks equal or above this version:

Example:

"frameworks": {
  "net451": { },
  "netstandard1.5": {
  "dependencies": {
    "NETStandard.Library": "1.5.0-rc2-24027"
  },
  "imports": [
    "portable-net45+wp80+win8+wpa81+dnxcore50",
    "portable-net451+win8"
  ]
 }
},
  1. Package your RC2 application as a Nuget package. I haven't seen how to do this from Visual Studio yet, but it can be done from the command line with:

    dotnet pack -o e:\packages

If you want to update it on every build you can add the following to the project.json file which updates the package automatically into a parent directory.:

"scripts": {
  "postcompile": [
    "dotnet pack --no-build --configuration Debug -o ..//..//..//packages"
]}
  1. Add the Nuget package into your .net 4.6 application. This can be done several ways. A simple way is to add the location you saved the package to as a packaage source reference.

  2. Increment the version number in the project.json file each time you build to ensure your other applications see the update.

Erikest
  • 4,997
  • 2
  • 25
  • 37
Gary Holland
  • 2,565
  • 1
  • 16
  • 17
  • 10
    It works but what a terrible experience. This is not the promised "csproj can reference xproj". Almost not worth doing this until the tooling gets out of preview. – mwijnands Jun 09 '16 at 07:24
  • I think you probably don't need that extra `net451` framework in there. – Asad Saeeduddin Jun 21 '16 at 13:14
  • I've tried this, but it gets kind of frustrating when debugging, because it doesn't always load all of the debugging information from the package. It also is bad, because you have to constantly update the version number of the package or else the nuget package cache will not grab the newest version. Then it complains that it cannot find the source code to step into when doing line-by-line debugging. – Kevin Oct 22 '16 at 20:47
  • 2
    creating a nuget package isn't necessary... once you add the requisite framework and build, you can reference the .NET CORE project from your .NET 4.6 application directly. – Jeremy Holovacs Nov 09 '16 at 01:22
  • is this answer relevant? – Akmal Salikhov Dec 12 '17 at 20:52
  • If the .net framework references the core that it cant use native. – lindexi Feb 28 '18 at 03:58
9

The answer is shown in a presentation

Only with ASP.NET Core RC 2 which is not released yet, a support for referencing xproj in csproj will be added.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Roman L.
  • 869
  • 1
  • 8
  • 15
7

Change your class library (and any dependents) to build against 4.6 as well .NET Core;

Change class library to build

This will now build both versions of the class library for you.

Debug folder with both builds

In your .NET 4.6 project (App) then add a direct reference to the class library's DLL found in the debug folder

Add direct reference

You can now import this namespace, and build against it. Although ReSharper (2016.3 EAP 2) seems to get confused and marks those lines in red - it's a stop gap until later .NET releases.

If you open up the application project file (.csproj), you'll see the reference added by framework.

enter image description here

NB: Build code dnx462 doesn't seem to work, complains about .NET framework not being installed, even though the project has a 4.6.2 WPF App.

wonea
  • 4,783
  • 17
  • 86
  • 139
  • 1
    it looks like this path to the .NET 4.6 DLL is an absolute path. Does this mean that another contributor to the project would need to create an exact duplicate folder hierarchy to match this in order to use the reference or does the reference auto-update? – Kevin Oct 17 '16 at 00:18
  • 1
    I've updated my answer and you can see it's a relative path. – wonea Jan 26 '17 at 11:40
4

I have been struggling with this too, but have found a better solution than the cumbersome nuget package solution. I found this on Stackify. This post only discusses having a separate solution, but it is pretty easy to use only one solution.

Separate Solution For .NET Projects

This options entails having two solution files along with two project files for each project using both .NET core and .NET 4.x.x. First create a fresh blank solution. Next create a new Windows "Class Library" (what you name it does not really matter at this point). Remove this from the solution so you can edit the .csproj file. Open the .csproj file and change the AssemblyName XML element to the .NET core project assembly name. You should make any other name related changes to the project now. Close the .csproj and rename it to the same as your .xproj file. Copy this to the same folder as the .xproj file.

Now that your new shiny .csproj file is ready, here is where the magic happens. Create a file called ProjectName.project.json and add this text to it (modify .net framework as necessary)

{ "runtimes": { "win": {} }, "frameworks": { "net461": {} }}

In the .NET 4.x.x solution, reload this modified .csproj and you can add your source files. I found the easiest way to do this is press "Show All Files" and click "Include in Project" in the right-click context menu for each file/folder . Now try to build the .csproj and it should build fine. If this does not build properly, try either reloading the project, or restarting visual studio.

Same Solution, but Two Projects

This is the same as the previous one, however with a few key differences. The name of the .csproj file MUST be different than the name of the .xproj (I just added a suffix, like MyProjectName.win.csproj and MyProjectName.win.project.json). These can be added to the same solution without a name conflict. You can even have the AssemblyName element in the .csproj be the same as the .NET core assembly name, because the output folder changes depending on .NET version

Final Thoughts

I found this solution so much better than the nu-get package option. The only minor thing to think about is all modifications to any references, nu-get packages, or any new files must be added to both projects; This is a small price to pay to avoid the terrible nu-get package option, though. Lets just cross our fingers and hope the VS team can get .xproj references in .cspoj files working as soon as possible.

I know I shouldn't post links, however I would like to give credit where it's due. http://stackify.com/using-both-xproj-and-csproj-with-net-core/

Kevin
  • 424
  • 3
  • 10
3

I found a very simple solution that works well, if you don't mind hardcoding a reference to either Debug or Release. You just manually add a reference to your xproj in the csproj file. Here is how you do it:

  1. Ensure that your csproj is using at least one nuget package. Most projects do, so this is not a problem.
  2. In Visual Studio, unload your csproj project
  3. In Visual Studio, right-click on the csproj file and choose "edit"
  4. Find the part in the csproj project file where you are referencing a nuget package. Ah... here's one:

        <Reference Include="Microsoft.CodeAnalysis, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> 
           <HintPath>..\packages\Microsoft.CodeAnalysis.Common.1.3.0\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
           <Private>True</Private>
        </Reference>
    
  5. Copy this and modify it to reference the DLL produced by your xproj project, like so:

     <Reference Include="HighFive.Server.Web"> 
         <HintPath>..\HighFive.Server.Web\bin\Debug\net461\HighFive.Server.Web.dll</HintPath>
         <Private>True</Private>
     </Reference>
    
  6. Save and close the csproj file
  7. Reload the project
  8. Rebuild all
  9. Presto!

Regarding hardcoding either a Debug or Release reference: For unit test projects, this is not a problem since you typically execute unit tests in debug mode. I am sure this could be made even smarter using MSBuild parameters to avoid the hardcoding but I didn't need to do it yet.

Craeg Strong
  • 165
  • 10
  • 2
    I've been able to use `$(Configuration)` instead of Debug and it's picked up the Debug\Release one so the HintPath looks like `...\bin\$(Configuration)\net461\...`. Also, it's worth setting the Project Dependencies to force the .NET core project to get built before the other project. – Samuel Sep 25 '16 at 06:17