Bind to a specific assembly version from GAC - c#

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.

Related

utilizing C# microsoft assemblies that are not in the GAC

My computer only has VS2019 installed with .net versions up to 4.8. I'm attempting to use the Microsoft.Build.Construction assemblies in a program i'm working on. When i go to add the reference->Assemblies, the only versions i have are 4.0.0.0. Based on my research, VS stopped adding assemblies to the GAC, so i'm forced to manually add the DLL from C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin in order to utilize the Version 15.1.0.0 that at least supports the SolutionFile calls.
So my question is this: should i push those versions to the GAC in order to be able to use them, or is there a better way to access non-GAC assemblies than how i did.
For MSBuild assemblies, you must follow the guidance of Microsoft strictly to avoid all side efforts. In general, the NuGet packages are recommended.
Change MSBuild references
To make sure that MSBuild loads from a central location, you must not distribute its assemblies with your application.
The mechanism for changing your project to avoid loading MSBuild from a central location depends on how you reference MSBuild.
Use NuGet packages (preferred)
For detailed information, please check out the long reference
Forget the GAC, just take the DLL in the Bin folder, copy it to your project folder in /References, and reference it from there. This way if you use version control, the specific version of the DLL follows the source code.
EDIT: As mentioned by Lex below, this is not a suitable solution for MSBuild assemblies, you should use the Nuget package instead.

Nuget package is required even though there is no reference to the package

In my solution I have a top level project with a bunch of dependent projects. One of the dependent projects has a required reference to the Nest nuget package. So in our nuget package config for the solution, I have Nest installed only on the project that references it.
The top level project has a reference to this dependent project, but no references to the Nest namespace. It builds without warnings or errors, however, in runtime, I have an issue saying
Could not load file or assembly 'Nest, Version=7.0.0.0, Culture=neutral, PublicKeyToken=96c599bbe3e70f5d' or one of its dependencies. The system cannot find the file specified.
When I manually install the Nest package on my top level project, it succeeds without issue.
Why does this occur? Shouldn't installing the Nest package on the dependent project resolve this dependency?
One of the dependent projects has a required reference to the Nest
nuget package.
Did you call Nest's function in the dependent project? VS will not copy the dependent project's assembly into top-level project if it finds the dependent project doesn't actually call(need) the assembly in code.
Why does this occur? Shouldn't installing the Nest package on the
dependent project resolve this dependency?
I'm not sure the cause of the issue with info available in your question, many factors can cause the strange behavior and sometimes VS version would also affect it...
Assuming you have a top-level project A and it depends on project B using Project Reference.
1.If both them targets .net framework, please make sure they use the same way to manager nuget packages.(Both using packages.config or both using PackageReference)
2.If A is .net framework project while B is .net standard project, please make sure the A is also using PackageReference format to manage nuget packages.
Cause .net standard(new SDK format) uses PackageReference packages, if A uses Packages.config and reference B, the build system will be confused about the different nuget formats in the build process. And we won't find the Nest.dll copied from B's output folder to A's output folder.
For this situation, try adding <RestoreProjectStyle>PackageReference</RestoreProjectStyle> into top-level A's project file.(xx.csproj) It will make sure both A and B can be restored as PackageReference style.
3.If A is .net framework with packageReference, and B is .net framework with Packages.config, right-click the packages.config and choose Migrate Package.config to PackageReference button. Also you may get some help from this document.
4.If your top-level project is .net core and B project targets .net standard, in VS2017, the nest.dll won't be copied into A's output folder, you can try adding <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to your A.csproj to resolve this issue. Similar issue see here. (And VS2019 16.3.8 has fixed this issue, this issue mostly occurs in VS2017)
And this behavior is also affected by VS version, if you're using VS2017, please update it to latest 15.9.17 for better experience. If you're using VS2019, please update it to 16.3.8.
Hope it helps :)

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.

Visual Studio projects copy dependencies from referenced project into output

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.

ASP .NET CORE could not find file or assembly with custom assembly

I've ran into a weird problem.
I basically have my own web-stack for .NET-core which I've built into a few .dlls, and I want to reference these from another ASP CORE-solution.
VS seems to find the assemblies, where I can navigate types etc.
I can also build the project without any issues, but when IIS then runs the server I get an internal server error stating:
FileNotFoundException: Could not load file or assembly 'myDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
The referenced DLLs are in the debug-folder, and the really weird thing is that if I create a new ASP Core project in the same solution as the web-stack, I can reference and use it without any problems.
Why is this happening only when running on a project outside the web-stack's solution, and what can I do to make it runnable everywhere?
The .NET Core Tooling in VS 2017 (< 15.3 preview) / .NET CLI < 2.0 doesn't fully support referencing assemblies on disk. You need to package the library up as a NuGet package or use a project reference ("same solution"). The technical reason is that all the required assemblies and versions are resolved during compilation and written to the .deps.json file. When loading arbitrary assemblies, this might fail because either the assembly or its dependencies cannot be found (or a conflict with each other).
for load the external dll in core project, needed to:
vs 2017 with version 15.3 or upper.
Microsoft.Extensions.DependencyModel NuGet package installed in your project.

Categories

Resources