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.
Related
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.
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.
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.
I have a API project that uses .net core project using full .net 4.6.1 I was updating one of my nuget packages that uses Identity Server 4 and was making sure it was not conflicting with some of my old code so I deleted the bin folder content.
I rebuild the project and its now unable to inject my nuget package saying it can't find system.net.http 4.1.1.0. After many hours of slowly ruling things out it turns out that when the project rebuilt and put all its DLLs into the bin folder it did not copy the system.net.http DLL.
What is odd is when I create a new .net core API project using .net 4.6.1 and delete the bin folder and rebuild it does copy the system.net.http dll.
So my question is - how do I make sure the DLL is copied into the bin folder so this does not happen to someone else working on the project?
Update 2017-03-03 11:00
So I have found out what is breaking my project but I cant work out why / how to fix it.
1) If you create a blank .net core API project change it to use .net461 clean your bin folder and build it you will see the System.Net.Http DLL within the folder "bin\Debug\net461\win7-x64".
2) Now add IdentityServer4 AccessTokenValidation to the dependencies
"IdentityServer4.AccessTokenValidation": "1.0.5"
3) Clear your bin folder again
4) Build project and you will see the System.Net.Http DLL is missing.
The project should still work when you run it but I am using a nuget package that needs that missing DLL...
System.Net.Http should be a reference in the project that uses it. Get the reference's properties and set the property "Copy Local" to true.
If all of the options you did didn't work, please try restarting (close / open as "admin") your visual studio, then clean / rebuild. This has fixed my problem.
We have a visual studio package (VS Package) that references two class library projects: Project A and Project B. Project A in turn references another class library project (Project B).
So the dependency structure looks like this:
VS Package
-> Project A
-> Project B
All projects exist inside the same solution and the dependencies have been set up as proper project references. When deploying the VS Package the assemblies from Project A and Project B are deployed to GAC. The assemblies are strong named. No binding redirection is specified.
We deploy several versions of the same VS package thus several versions of Project A and Project B assemblies are in GAC. The problem is that no matter which version of VS package is executed it always loads the latest assembly versions from GAC.
How can we force the correct version of the assembly to be loaded from GAC that is the version used when building the VS Package project?
Thanks.
Edited my original post to more accurately describe my situation.
This should do the trick , but I cant recommend it you should avoid using the GAC and have your librarys close.
Assembly SampleAssembly;
SampleAssembly = Assembly.LoadFrom("c:\\Sample.Assembly.dll");
For more information read the manual
In the Properties window for the reference, you may set Specific Version to true.
You may add a Binding Redirect. This can be done at various levels such as machine, app, or by a publishing policy.
See here for guidance.