NuGet - Package dll is NOT copied to output directory - c#

I have a .NET 5 class library project. This project is dependent on a NuGet package. My code will not compile without this NuGet package. However, once I have added this package, my code successfully compiles. However, I've noticed that the bin/debug/net5.0 directory does not have a .dll for the NuGet package like I expect. The other NuGet packages that I'm referencing have .dll files in the bin/debug/net5.0 directory like I expect. My problem is, when I use this library in my runner, it fails to run because it's looking for the .dll associated with the NuGet package, but it's not there.
Why would the .dll for a NuGet package not get copied to the bin/debug/net5.0 directory? I can see that the NuGet package has a .dll file in it's [version]/lib/netstandard2.0 directory. I need that .dll in my bin/debug/net5.0 directory. What am I doing wrong?
Update
I believe I've isolated the issue. To isolate the issue, I did the following:
Created a new .NET 5 console app. Added the LiteDB NuGet package. Added a reference to the LiteDB namespace. When compiled, the LiteDB.dll is in the bin/debug/net5.0 directory as expected.
Created a new .NET class library project. Added the LiteDB NuGet package. Added a reference to the LiteDB namespace. When compiled, the LiteDB.dll assembly is not in the bin/debug/net5.0 directory as expected.
The console app .csproj includes <OutputType>Exe</OutputType>. The class library project does not include an OutputType element. This is the only difference. However, since the OutputType defaults to library, this makes sense. However, the question is, how do I get the LiteDB.dll assembly to appear in the bin/debug/net5.0 directory for a class library project. That's what I need.

Related

.Net Plugin Architecture Not Working with Nuget

I have a .Net Core 3.1 console application that loads plugins. One of my plugins connects to Sqlite and so it has a Nuget dependency on Microsoft.Data.Sqlite. However, I'm getting a missing DLL exception from the console app when loading/running the plugin because the following path doesn't exist:
MyConsoleApp\bin\x86\Debug\netcoreapp3.1\runtimes\win-x86\native\e_sqlite3.dll
I also have an MsTest project which tests this Sqlite plugin project. It does not have the same problem. Apparently the runtimes folder and contents will automatically exist if a Visual Studio project (1) is some kind of executable and (2) has a pertinent Nuget or project reference.
Following those rules, two of my three Visual Studio projects do not have the runtimes folder:
The plugin has a Nuget dependency on Microsoft.Data.Sqlite, but does not have the runtimes folder because the plugin project is a DLL...not an executable.
The MsTest project which tests the Sqlite plugin does have the runtimes folder and contents because (1) it it is a type of executable and (2) it has a project reference to the plugin project (which in turn references the Nuget package).
The main console app is an executable, but (intentionally) doesn't have a project reference to the plugin. Thus it does not have the runtimes folder.
How do I solve this? As a hack I have simply copied the missing DLL into the output target directory for the console app.
Also, if I add a project reference from the console app to the plugin, this problem is solved. But, as stated, I don't want the console app to have project references to any plugins. Plugins should be discovered dynamically. I think fixing this may have something to do with creating a nuspec file. However, the documentation for nuspec files has no commentary about addressing this.
.Net Plugin Architecture Not Working with Nuget
Just as you said that, the lib plugins project which references Microsoft.Data.Sqlite does not have the runtime folder and when an exe project reference the lib plugins project, the runtimes folder will be copied into the the exe project's output folder.
Solution
1) Since you do not want to reference the lib plugins project for the console project, you can just do a copy task in msbuild from the MsTest project's runtimes folder.
Write this target in the xxx.csproj file of Net Core 3.1 console application:
<Target Name="Copy_Runtimes" AfterTargets="Build">
<ItemGroup>
<CopyItems Include="..\MsTest\bin\Debug\xxx\runtimes\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(CopyItems)" DestinationFolder="$(OutputPath)runtimes\%(RecursiveDir)%(Filename)%(Extension)')"></Copy>
</Target>
2) Besides, you can also install the nuget package called sqlite in the net core 3.1 console application, and this package only contains the runtimes folder and does not include other com dlls for using.
It is actually a pure service package for providing runtimes folder.
You can install this package in your console project directly and if you are not satisfied with this, you can only try solution 1 to solve the issue.

Keep NuGet packages private

My solution uses NuGet packages from a private feed. I would like to keep these NuGet packages private. However, when I copy the .exe file to be used for deployment I am forced to copy the NuGet package's corresponding .dll file in order for the .exe file to run. There is nothing stopping someone from copying and using that .dll in another application.
Is there any known solution to this problem? I can't even figure out how to embed the NuGet.

Nuget pack - Multiple errors with Microsoft tutorial

Following the Microsoft tutorial on NuGet .NET Framework here. I AM using VS 2019.
Everything goes fine until I get to NuGet pack. I get the following error:
'C:\Users\erics\source\repos\AppLogger.vs\AppLogger\v16\Server\sqlite3\db.lock' because it is being used by another process.
The .vs folder is created automatically in all my projects. If I close VS and delete the folder it is recreated. If I close the solution and then try pack again I get:
WARNING: NU5100: The assembly 'AppLogger\bin\Debug\AppLogger.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project. Move it into the 'lib' folder if it needs to be referenced.
WARNING: NU5100: The assembly 'AppLogger\bin\Release\AppLogger.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project. Move it into the 'lib' folder if it needs to be referenced.
WARNING: NU5100: The assembly 'AppLogger\obj\Debug\AppLogger.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project. Move it into the 'lib' folder if it needs to be referenced.
WARNING: NU5100: The assembly 'AppLogger\obj\Release\AppLogger.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project. Move it into the 'lib' folder if it needs to be referenced.
The NuGet docs were written before SDK style projects existed (before .NET Core was created), and mostly has not been updated since. Therefore the tutorials are very much out of date.
My 30 second tutorial for creating NuGet packages:
Create a "Class library (.NET Core)" project, even if you want to target the .NET Framework. You can also do this from the command line using dotnet new classlib. If you want to target the .NET Framework, right click the project in Solution Explorer, and select "edit project file" (or edit the csproj in your favourite text editor) and change <TargetFramework>netcoreapp2.2</TargetFramework> to <TargetFramework>net472</TargetFramework>, or whatever .NET Framework version you want (remove the dots so 4.7.2 is 472, 4.7 is 47, not 470). Finally, right click the project in Solution Explorer and select Pack, or run dotnet pack from the command line.
Packing SDK style projects (or traditional projects with the MSBuild pack targets) is much improved over using nuget.exe pack and nuspec files, so I strongly suggest using that instead. We (NuGet team) really need to find the time to update the docs.
I've checked the tutorial and reproduced same issue.
When VS is running with current project AppLogger opened, the .vs folder is used by it. (Create a new solution, and navigate to the SolutionDir, you can find the .vs is occupied by VS since we will fail to delete it when VS is running)
According to this error message, when using nuget pack command, it will also try to read some data from .vs folder. But the .vs has been occupied by VS and the nuget.exe can't access it. So the error occurs.
I would think it needs some additional note to the document like:
Note: To run the nuget pack xxx.nuspec successfully, you should close VS instance before it.
If I close the solution and then try pack again I get the warnings:
The warnings indicate that the assemblies you want to package should be copied to lib folder so that the project who loads this package can get the assembly. A simple way to reslove this error messgae is: Create a lib folder in the project folder and copy the xxx.dll into it. Then use the nuget pack command again.
Then the xxx.nupkg we created contains the assembly.
Create a new .net fx project, load the xxx.nupkg, now we can reference the AppLogger.dll correctly.
(Also, the warning would still displays:WARNING: The assembly 'lib\AppLoggerSampleMyTest.dll' is placed directly under 'lib' folder. It is recommended that assemblies be placed inside a framework-specific folder. Move it into a framework-specific folder.) But it's just a warning, which suggests to help make a better nuget package structure.
And according to your last comment, you're working in local dev development. Then you don't have to create nuget packages for this situation. I think class library project template itself is enough for your situation.
(If they are in same solution, right-click project=>add=>reference, if not in same solution, you can right-click solution=>add existing project to include the class library project)

Nuget packages - HintPath after Deployment?

I have a C# class library project in VS 2017 that I'm trying to make work with Nuget packages in a somewhat strange release environment.
The project has a packages.config with standard Nuget packages such as EntityFramework 6.2.0 for example.
The project compiles fine, but the release environment is setup so that only the class library project DLL itself is deployed (no dependent DLLs).
The class library DLL needs to resolve the DLL references in a completely different directory such as C:\Dependencies, instead of the deployment location C:\ClassLibraries.
How can I resolve the dependencies that are in a completely different folder after release?
Edit: I already tried this HintPath Exists trick posted here, but it didn't work:
.csproj multiple hint paths for an assembly
Edit 2: I don't have access to the EXE that calls this DLL or the app.config associated with the EXE that calls this DLL.

Publish .net standard library with all it's dependencies?

I have created a system which loads dynamically a library and executes it's main class.
Everything works perfect, the problem I have is how to publish this DLL with all it's dependencies. As no executable project is referencing it I have to manually retrieve the dependencies: try to load the library, check the needed DLL's, go to the NuGet cache folder, copy the libraries, try again, check if it complains about more dependencies and so on until it has all the required libraries.
This is a true pain and I haven't found any information on how to do this, is it possible or am I stuck with this?
The library is a .net standard 2.0 library, I did this before with .net classic and the output folder always contained all the required libraries even the ones comming from a NuGet package, but with .net standard something has changed and now only libraries from referenced projects are being copied, no referenced NuGet package is being copied to the output folder.
Cheers.
Try:
dotnet publish
All the dependent libraries should be copied to the publish output folder.
At the time of writing, it looks like it's by design and there's quite some fuss and confusion about it, see logged issue on GitHub.
Moreover, when publishing a NuGet package for project A referencing project B,
B becomes a NuGet dependency in A; B's assemby is not included in A's NuGet package.
I deal with it by publishing my own NuGet packages.
I only don't like it to have a NuGet package for project B if that one is only relevant to be used with/by project A, as it will appear seperately in my NuGet feed.
TLDR: Convert your Class Library project into an Application, publish the application, and use application DLL as a library.
The long of it:
I tested this approach by deploying a full build with a plugin with many external dependencies to Ubuntu 18.04 and it ran perfectly.
Create a new project of type Console Application instead of Class Library. Put all your library code files into the Console Application and add the dependencies. Get rid of your original Class Library project (you don't need it anymore). Finally, publish the Console Application. You will get a DLL with all of the dependencies. You can use this DLL like any other DLL.
I suggest naming the console app project with "Library" on the end of it and adding a README just to document its not really an application even though the project is configured to build as one.

Categories

Resources