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.
Related
I want to write that C# code convert-nunit-3-nunit-2-results-xml-file, but despite the added nuget package i'm missing the dll in my project.
I see it in the tool's directory of the package cache, but missing it in my project.
What do i overlook?
My project is at present for .Net Core 2.1. Is my issue therefore related to this: Add support for net standard ?
I'm new to .net and don't understand all the differences so far.
As zivkan explained, the package is a tool. In fact, it's an extension to another tool, the NUnit engine package. The NUnit engine knows how to find and use the extension.
NUnit does not publish a package that is intended for use by your code as a library, because we would then have to support it as a library in addition to it's use as an extension to NUnit.
However, NUnit's MIT license allows you to use the source code, which you can find at https://github.com/nunit/nunit-v2-result-writer
Since the code has not yet been ported to .NET Core, you would have to do that yourself.
You didn't overlook anything. Not all NuGet packages are libraries.
NuGet has conventions on how files must be packed in order to use various features. For example, files in the content or contentFiles get copied into the project directory, or build output, depending if the project using the package uses packages.config, or PackageReference. If the package author wants to give you a library that you can use in your code, they must put the library in the lib directory in the nupkg (technically it could be in ref, but those don't get copied to build/publish output, they're only used at build time). The tools directory is, unsurprisingly, intended for tools packages. It's often used by unit test runners, or in this case, a report generator.
So, since the package puts the dlls in the tools directory, this means the package author intends the package to be a tool to assist you during development, but not as a library for you to use in your code. You could try contacting the package author to see if they have published another package with the same dll, this time in the lib directory, so that you can use it your project.
Otherwise you'll need to find a solution that doesn't rely on NuGet bringing you this dll as a library. One option is to have a packages.config file that extracts the package in a solution packages directory, and then you use a dll reference to the dll. Your build script would then need to first restore the packages.config file before building your project. Another option is to check in the dll into your source control management tool, if the dll's license allows that, and again have a dll reference to it.
The setup is like this:
A Xamarin.Android application, which depends on Android class library
(at least that's what the template is called in VS)
Said class
library, the purpose of which (not entirely relevant, but FYI) is
interfacing with a REST service and has a dependance on the famous
Newtonsoft.Json NuGet package.
An NUnit test project for said
library.
IDE is Visual Studio 2017, latest version.
If you build and deploy the app on the phone, everything is fine.
However, if you try to run tests from the tests project, it says that it can't find the Newtonsoft library.
I've even managed to find a sort of reason: when the library gets built, it's dependancies aren't packed inside, and they are not copied to build directory.
When .apk is built for the phone, the dependancies ARE getting packed inside.
However, when NUnit project builds itself, it only takes the library, and the dependancies are nowhere to be found.
However, there's no interface to control the behaviour of NuGet "Package Reference" type dependencies (blue ones), the properties window is empty for them. And I found no way to add NuGet packages to this kind of project as a ".config" type of dependancy (grey one).
There is a workaround - you can add the Newtonsoft package to the NUnit test project, then it gets copied to the build directory and the Android library works with it, however it doesn't feel right to me. Tests don't need that reference and it has no business in that project.
How to control NuGet packages in Android Class Library?
Your workaround is the correct solution, you don't need to worry too much about it.
That is because the Newtonsoft package is not used directly in your NUnit test project, so Visual Studio / MSBuild doesn't know if your test project needs this Newtonsoft library. In order to avoid reference pollution in NUnit test project, Visual Studio / MSBuild tries to only bring references over into NUnit test project that it detects as being required by project Xamarin.Android application.
So, to resolve this issue, we often add Newtonsoft to the test project or give a copy task to copy it to the test project.
See This Thread for some more details.
Looking for an answer to another question I now found info that my described behaviour is a known problem, described by .NET developers here:
https://github.com/dotnet/standard/issues/481
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.
Is it possible to make Visual Studio to copy all dependencies of referenced projects into the output path?
Example
In the Solution, Project A (Library, .NET Standard) defines some functions and is dependent on Library L1 (via NuGet) and Library L2 (local .dll, referenced and copied to project)
Project B (Console Application) references Project A.
When building B, The output folder contains all direct dependencies of B and A.dll. L1 and L2 are not available in the output. Therefore, the program does not work correctly.
How can I force VS to copy also L1 and L2 to the output of B?
The only way I found so far is packing A as NuGet, but this seems to be unnecessary overhead and uncomfortable. I think I am just forgetting something everyone else seems to know...
Edit (clearifying Example)
My solutions consists of two projects.
Project MongoWrapper
.NET Standard 2.0 class Library
depends on NuGet MongoDB.Driver package
Actually uses this dependency (no zombie dependency)
Project ConsoleUser
.Net Framework 4.6.1 Console Application
References MongoWrapper project
Actually uses MongoWrapper
Observation
When debugging the ConsoleUser application, it compiles and starts. During runtime, when it calls a method in the MongoWrapper which uses the MongoDB.Driver, the application crashes, as the MongoDB.Driver dependency was not copied into the output folder of the ConsoleUser.
How to fix this?
The problem was introduced by the usage of .Net Standard library and a .Net Framework application.
TLDR
Open the .csproj file of the .Net Framework project with a text editor. Inside the first PropertyGroup add the line
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
Save the file, reopen Solution in Visual Studio and perform Clean & Build
Dependencies in different project file versions
.Net Framework projects use an old version of the .csproj project files. References/Dependencies are stored in the additional packages.configfile. By default, building a .Net Framework project makes the system to search for a packages.config file in the referenced projects. If no such file is found, the build task treats the referenced project as having no dependencies. Therefore, in the example, the MongoDB.Driver library is not added.
By adding the proposed line in the .csproj project file, the build task searches the project file of the referenced project for dependencies, where they are stored in .Net Standard project files.
.Net Core projects by default search for the newer project file structure.
The default behavior for new projects can be set in the Options -> NuGet -> General -> Package Management
Is it possible to make Visual Studio to copy all dependencies of referenced projects into the output path?
Yes.
This is what publishing the application does - it prepares the application for deployment. When you publish, it will include all of the dependencies that the application requires to run in the output.
Use the Publish tool to deploy to a local folder. The exact options available depend on your app type. In Solution Explorer, right-click your project and choose Publish, and then choose Folder. For more information, see Deploy to a local folder.
Tutorial: Publish your Hello World application with Visual Studio 2017
Also see: .NET Core application deployment.
The setup: I've created a library targeting .Net Standard 2.0 in VS 2017 and this library uses NuGet to reference a 3rd party driver and manage its dependencies. So far, so good.
The next step is to create an application that uses the (shared) library, in this case a console app targeting .Net Core. I can, of course, add a reference to the DLL(s) that form the shared library. That compiles but doesn't run because the 3rd party stuff is missing. I could of course just copy all required DLLs to the application but for obvious reasons I'd rather use NuGet.
I'm not very experienced with NuGet, never used it in this constellation and having read articles like NuGet cross-project dependency I'm getting the impression I need to fiddle with the application's project file in order to get the library in a complete form but surely that can't be the way forward.
So my question is - is the problem on the side of the library, i.e. do I need to build or export in a particular way, or on the side of the application which, IMHO, shouldn't need to know that level of detail about some library it consumes.
Any help much appreciated!
I'm sharing a large, complicated library this way with several other solutions.
First, set up your library. Right click on the library's project name and choose Properties. About halfway down you'll see a tab labeled Packages. You can use that to auto-generate the NuGet package every time you rebuild the project. Just increment the version number. I use four position version numbering -- the first three are semver-style (major release, minor release, patch release), and the fourth one I increment manually for each new build.
I recommend creating a folder on your drive or network specifically for your local NuGet packages. You can create folders under that for each project. Then you point your debug and release build output to that project folder, and the NuGet package will be generated there, too.
Finally, back in Visual Studio, go to Tools -> Options -> NuGet Package Manager -> Package Sources and add that top-level folder as a package source.
From there it's simple -- open your NuGet dependencies in your consuming app. There's a drop-down at the top right where you can choose the package source. It will automatically search all the child folders and find whatever packages you've created. Now when you tweak your library, it's just a single click to update the client apps.