I have a .Net 4.6 class library X, whose x.dll I'm referencing in my .NetCore Console application.
However, when I try to run the console application, it just throws an error saying that the dll does not exists under "bin\Debug\netcoreapp2.1\bin" folder. Whereas, the "bin\Debug\netcoreapp2.1" does not have a bin folder.
I could see the x.dll of my class library under bin\Debug\netcoreapp2.1. but no bin folder.
I tried searching this issue over the internet but couldn't find anything.
The problem here is that you can't reference a .NET Framework dll from a .NET Core application. To get around this, you can multi-target your class library to both .Net 4.6 and .NET Standard.
Check .csproj file of your .NET Core project.
There should be something like this
<ItemGroup>
<Reference Include="X" HintPath="..\bin\Debug\netcoreapp2.1\X.dll" />
</ItemGroup>
You should specify a correct path to the X.dll.
Note that it is not the best practice to reference .NET Framework libraries from .NET Core application. You would have failures if you forgot to check that .NET Framework library is compatible with .NET Core runtime and run your application on Linux.
Related
Setup
Say I have a .Net Standard 2.0 class library project and I add a Nu NuGet package that is compatible with .Net Standard 2.0 to it.
I then reference that class library project from both a .Net Framework console project and a .Net Core console project.
To restate with a picture:
Question
How does each of the console applications deal with getting the right NuGet code for their type of application?
Notes
Note: I tried this using Microsoft.Extensions.DependencyInjection, and it works fine in the .Net Core 3.1 console app, but throws a "File Not Found" exception in the .Net Framework 4.7.2 console app (looking for the Dependency Injection DLL). This leads me to believe that .Net Standard 2.0 NuGets are really .Net Core NuGets...
Note to the Note: I am trying to understand what happens here, not fix the "File Not Found" issue. (That is easily fixable by referencing the Microsoft.Extensions.DependencyInjection NuGet in the .Net Framework 4.7.2 console app).
In your scenario two different package resolution startegies are used. There is the old way of managing packages with packages.config and the new way with PackageReferences. There is also the old project format of .NET Framework projects and the new SDK-style format that was introduced for .NET Core, but is also usable in .NET Framework applications.
With the old project format that is still used by most existing .NET Framework applications regardless of packages.config or PackageReference, the .NET Framework Console application is only able to access the class library, but not the assemblies of its referenced NuGet package, because it is not a direct reference but via your library, hence indirect. This is als called a transitive dependency.
In the new SDK-style project format with PackageReference, this is fundamentally different. There, transitive dependencies are possible. This means, that your .NET Framework console application can access the class library project, as well as its referenced assemblies via the NuGet package.
The SDK-style format with PackageReference is the default for .NET Core projects, so they support transitive dependencies out of the box. Only with the old project format you have to add NuGet packages manually, because it cannot access the transitive dependency through the class library. You can migrate existing .NET Framework projects to the new SDK-style format, to enable the same behavior as in .NET Core.
If a .NET 462 project references a .NET Standard 2.0 dll the dependencies are not copied to the output bin folder.
It works correctly when the .NET Standard 2.0 project is referenced as <ProjectReference /> and <RestoreProjectStyle>PackageReference</RestoreProjectStyle> is added to the .NET 462 project.
My .NET Standard 2.0 project lives in a different solution and therefore cannot be added as project reference.
Is there a solution to this problems, that maybe takes the deps.json in the bin folder of the .NET Standard 2.0 project into account?
Or is the only solution to add the .NET Standard 2.0 project to all solutions, where projects have references to it?
If you cannot add the project as a project reference, consider using NuGet to consume a built package (and the contained dependency graph).
At the time of writing, .net standard projects and their dependencies cannot be referenced from a set of files (like produced by dotnet publish on the .net standard project) since the graph of NuGet packages needs to be resolved for the target executable project's framework (core, .net framework, uwp, ..) and certain build logic that needs to run during build & publish for the resulting executable project is not being run for .net standard projects.
Like so:
One solution (I assume this must be ASP.NET Core?)
Project 1. Target Framework is .NET Core 2.1
Project 2. Target Framework is .NET Framework 4.5.1. A class Library that handles data access. The reason I am asking is Project 2 contains legacy dependencies that we do not have time to migrate at the moment.
The solution has nothing to do with the target frameworks utilized. Target frameworks apply to projects, so you can have every project target something different in a solution and it doesn't matter for squat from the perspective of the solution.
Where problems come in is when you have project dependencies. In order to have a dependency on a project targeting a different framework, the all the frameworks being utilized must in some way be compatible with each other. You could for instance reference a .NET 4.6 project from a .NET 4.7 project, because ultimately .NET 4.7 is a superset of 4.6.
Speaking more directly to .NET Core and your scenario here in particular, no, you cannot reference a .NET 4.5.1 project from a .NET Core 2.1 project, but you can reference a .NET 4.6.1 project. The issue at play here is that .NET Core's ability to work with .NET Framework dependencies is dependent on .NET Standard. .NET Standard 2.0, the first version to support interop between .NET Core and .NET Framework requires at least .NET Core 2.0 and .NET Framework 4.6.1. If you can target that project to at least 4.6.1, then yes, you can reference it.
However, .NET Framework includes stuff that .NET Standard does not, and therefore things that .NET Core does not. Even though Visual Studio will let you add the reference, it does not guarantee that all or even part of the library can actually be utilized. In fact, you'll get a warning to this effect after you add the reference. It's on you to verify that the dependency works correctly, and then you may suppress the warning at that point.
Mostly, the things that are going to trip you up are platform-specific Windows APIs. For example, System.Drawing is a problem because .NET Core is cross-platform, where System.Drawing uses Windows-specific APIs. In some cases, you can still utilize these incompatible libraries as long as your app stays firmly tied to Windows. Again using System.Drawing as an example, there is a CoreCompat package that will allow you to use System.Drawing from a .NET Core project, which then means you can utilize libraries that use System.Drawing as long as you build and run on Windows. If you attempt to take your app to Linux, it'll blow up. You can use compiler directives to shim in different code specifically for Linux and Mac to compensate, though.
Long and short, there's no hard and fast "yes" or "no" answer here. You'll need to do some extensive testing to make sure everything works as it should. If things do break, you may be able to shim in support with one of Microsoft's compatibility packages, but you will not be able to move off of Windows until you replace the code that requires that. That gives you some breathing room in upgrading, but don't expect you'll get all the promise and allure of .NET Core just because it lets you add the dependency.
Yes, you can as long as you do not plan to host in non-windows environment.
However, ASP.NET Core 2.1 app must target .NET Framework
4.6.1 or above although it can still reference .NET Framework 4.5.1 class library.
(Click the image to view in full-screen)
If you want to switch the target framework, you just modify .csproj file.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
</Project>
Note: you cannot easily switch it back and forth. Whenever you switch it, you'll have to restore NuGet packages.
2nd option is ASP.NET Core 2.1 app targets .NET Core 2.1 and still references .NET Framework 4.5.1 class library.
I prefer this option because you won't have to change anything to ASP.NET app when you later rewrite the class library to target .NET Standard or .NET Core.
you don't need to add a target framework, all you need to do is referencing the project to your .Net core one as a package, by adding the following to the .csproj file:
<ItemGroup>
<Reference Include="MyProjectName">
<HintPath>path_to_the_project/MyProjectName.dll</HintPath>
</Reference>
</ItemGroup>
Once done, remove the bin folder in your .Net Core project, restore packages, rebuild the project, then you're good to go.
Hope you'll find this useful.
I've just created a fresh project using dotnet new web. My Google-foo may be failing me, but I didn't find anything relating to my answer (please link to another SO answer, or relevant documentation if I've missed something obvious).
If I want to ensure this new project is .NET Standard 2.0 compliant, what do I now do?
It is not inherently possible to run a netstandard project as an executable. Since netstandard was designed to be used for libraries.
In order to develop your web application entirely in netstandard2.0, you would have to create a separate project that targets either .NET Core or .NET Framework to execute your library that contains your web app (developed using .NET Standard).
1. Executable Project (ex: console app)
-- Target Framework: netcoreapp2.0 / net462
2. Web Application Project (library)
-- Target Framework: netstandard2.0
You can use the following steps to change the target framework of your project.
Step 1. Target the desired framework
Right-click on your project and select Edit *****.csproj
In the .csproj file, you need to replace the target framework to the .NET Framework.
Example .csproj file:
<Project Sdk="Microsoft.NET.Sdk.Web"> //<-- note the .Web for the web template
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
For a list of the Target Framework Moniker (TFM) (ie, net47, netstandard2.0, netcoreapp2.0, etc.*) you can check this link out:
https://learn.microsoft.com/en-us/dotnet/standard/frameworks
Step 2. Run dotnet restore
Go to your output window and run dotnet restore.
Note: Sometimes Visual Studio may misbehave (depending on which update you have installed), so you may have to close and re-open your Visual Studio. Otherwise, sometimes a clean/re-build may do the trick.
Targeting both frameworks
You can pick one or the other, or even target both frameworks.
<TargetFrameworks>netcoreapp2.0; net47</TargetFrameworks> //<-- note the plural form!
NET Standard is for class libraries. Applications must target netcoreapp* where * is a version number. The following shows the compatibility matrix: https://learn.microsoft.com/en-us/dotnet/standard/net-standard
For example, .NET Core 2 can consume .NET Standard version 2 and below.
I do have an ASP.NET MVC Core app and would like to add a Class library in my project.
I added it in my project via "Add Reference" > "Browse" > select DLL and done.
I added it on code like
using PagarMe; // works good on code
And I was able to compile and run the app. however when the user goes to a page where the lib is referenced then I got the fallowing error.:
FileNotFoundException: Could not load file or assembly 'PagarMe.Pcl, Version=2.0.6372.16631, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
What I already done.
I checked the output bin folder and the Dlls files are there.
Both DLLs are compiled with "Any CPU" configuration.
I tried PCL and non-PCL Version.
App Target framework: .NETCoreApp 1.1
Default Class Library Target Framework: .Net Framework 4.5.
Portable (PCL) Class Library Target Framework: .Net Framework 4.5 and ASP.Net Core 1.0
What can I do in order to use Class Library or PCL library into my Core App?
In .NET Core you no longer use Portable Class Libraries, but you target the correct version of the .NET Standard Library. Some PCL or Shared Classes may use some unsupported
references.
To solve this please try one of this:
1. Rebuild your Class Library to target .NET Standard. .NET Standard 1.6, for instance, is supported by both .NET Core 1.0 and .NET Framework 4.6.1.
.NET Standard can be thought of as the next generation of Portable Class Libraries (PCL). The .NET Standard improves on the experience of creating portable libraries by curating a standard BCL and establishing greater uniformity across .NET runtimes as a result. A library that targets .NET Standard is a PCL or a ".NET Standard-based PCL". Existing PCLs are "profile-based PCLs". (Taken from the documentation)
2. Target your app to .NET Framework.
You could build an ASP.NET Core application to target the full .NET Framework in stead of .NET Core only. This gives you the advantages of ASP.NET Core, without the limits of .NET Core.
ASP.NET Core != .NET Core