I've build 2 modules for DNN and they work great. Both modules depend on a separate project, that is included by a dll file. Both installations include that dll to the bin folder.
Now if one of the modules gets an update with a newer included dll (assembly and file version is increased for every new version), the older will be overridden by the new dll.
But what if that situation is reversed? I install a version with the older dll file, will the newer be overridden by the older version? I read somewhere that this shouldn't happen, but can't find any information about it.
DotNetNuke manages that for you, as long as you include the version number in the Module install manifest (.dnn file), see here for more information: http://www.dotnetnuke.com/Resources/Wiki/Page/AssemblyComponent.aspx
Related
We re working with GIT. We have a problem with control with the versions of DLL files. Sometimes one person work on dll version 12.0.0, and he want to install new version of this file into only to 8 projects (we have 10 projects inside one solution). After this he pushing new files int repo. Our compilator man when he pulling from repo and compiling the files, has older DLLs version (example 12.0.0 not the newer installed). Our exe file require newer version than 12.0.0, but inside directory we have 12.0.0 version.
How can we control this inside visual studio or inside another application?
.NETCore just litters your disk a lot worse, too many versions, too many assemblies, too many standards and no GAC. Hopefully they'll get their act together sometime soon. – Hans Passant Aug 17 '17 at 10:37
No, it just keeps getting worse. : \
Have a .NET Standard 2.0 class library that references Microsoft extension classes. When we deploy to the server, we get runtime binding exceptions. My questions first:
Why aren't binding redirects being generated for transitive dependencies?
Since they're not, how do I come up with a full list to add manually?
How does the compiler know what version to redirect to unless it intends for me to deploy the version it compiled against?
How do I come up with a list of DLLs to deploy - excluding framework DLLs but including anything that wouldn't be on the server?
Is a nuget package broken if the assembly version in \ref\ is lower than the assembly version in \lib\?
Details:
We have a class library compiling against .NET Standard 2.0... it references Microsoft.Extensions.Configuration.Json.
MimExtension
\--Dependendencies
\--Packages
\--Microsoft.Extensions.Configuration.Json (5.0.0)
\--System.Text.Json (5.0.0)
\--System.Buffers (4.5.1)
System.Buffers resolves to \.nuget\packages\system.buffers\4.5.1\ref\netstandard2.0\System.Buffers.dll. The file version in that directory is 4.6.28619.1, date 2020/02/19. .NET Reflector shows the assembly version as 4.0.2.0.
The \lib\ version of that DLL is \.nuget\packages\system.buffers\4.5.1\lib\netstandard2.0\System.Buffers.dll... same file version and date, but the assembly version is 4.0.3.0.
Compiling the DLL gives me a .dll.config file with binding redirects that I could copy into the consuming application's app.config - but System.Buffers.dll and System.Text.Json.dll aren't there. Microsoft.Extensions.Configuration.Json.dll also isn't there - though another nuget package, Microsoft.Extensions.Configuration.Abstractions.dll, is.
I'm assuming this means the compiler thinks no redirect is necessary for the DLLs that aren't in there (see question #3). It makes sense that only DLLs with conflicts across references get added to the binding redirects (if that's what's happening), but conflict or not, our app won't bind to the \lib\ version of the System.Buffers.dll the compiler uses and RTE's (question #1).
To resolve this I can add binding redirects manually. But how do I look at all the nuget references in my project and determine (recursively) what version was chosen for each dll? Short of dumping verbose build output to a text file with some fancy regex and an hour of copy and paste, that is (question #2).
Note: I can add <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to the .csproj file and get all referenced dlls dumped to the output directory - including .NET dlls like System.Threading.dll and System.Runtime.CompilerServices.Unsafe.dll- but that still doesn't get me a full list of what versions each one are... especially since I need assembly versions, which I can't even display in explorer.
Regarding that... some of the binding redirects generated automatically are for .NET assemblies like System.Threading... does VS really expect me to deploy the version of System.Threading I compiled against? For that dll, I have newVersion="4.0.11.0"... our server has assembly version 4.0.0.0, file version 4.8.3761.0. VS expects me to deploy assembly version 4.0.11.0, file version 1.0.24212.01 (wtff?!?). The 4.0.11.0 version pulled down by nuget is dated 2019/12/26... the 4.0.0.0 server version is dated 2021/01/21.
I'm guessing that's a Core vs. Framework versioning wtf - but binding redirects don't care. The app that will load our library is .NET Framework 4.8... am I supposed to deploy the System.Threading 4.0.11.0 dll with my app, or manually change the binding redirect and let it load the server's version? It's absolutely ludicrous that a core DLL has a higher assembly version than its newer .NET Framework counterpart (question #addingnewonesasigo).
So when we're referencing nuget packages, how do we know what needs deployed and what doesn't (or worse, shouldn't be)? (question #4) I feel like the build process should copy dlls that aren't part of the framework/won't be in the GAC to the output directory - but there's nothing TIAO to indicate that in the nuget package specs.
Regarding #5... shouldn't the dlls in a nuget package have the same version in the \ref\ and \lib\ folders? The breakdown in Microsoft.Extensions.Configuration.Json is in System.Text.Json... S.T.J's .nuspec lists a .NET Standard 2.0 dependency to <dependency id="System.Buffers" version="4.5.1" />. So why would the System.Buffers.dll nuget cache have different versions in \ref\ and \lib\? Shouldn't they both be either 4.0.2.0 or 4.0.3.0?
There are a lot of questions out there on this - even some specifically to System.Buffers. But nobody has resolved this satisfactorily (that I can find) for a class library. I'm going to try adding a scratch website to the solution and reference the library - just to see whether .NET gets the necessary dlls/redirects in place for its only love: Web
Update
I manually added a binding redirect to 4.0.3.0 for System.Buffers... and immediately got the next mole to whack: Could not load file or assembly 'System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies
And so it will go, until we find a way to list everything that VS probed. And without 100% regression coverage, there's no guarantee we won't miss something when we deploy.
For an executable, dotnet publish; and ship the resulting folder is always correct.
But for a dll compiled against .net standard; I've only had success building a nuget package and referencing it and letting the compiler (whole package thereof) figure out what final dlls the project needs. You can make a nuget package with dotnet pack.
I have never needed binding redirects to link .netstandard to .net framework.
Compiling the library for specific platforms pulls the dependent DLLs into the bin folder. This makes sense in retrospect - compiling for .NET Standard is only meaningful when the target platform isn't known and won't be chosen by the developer of the library. That scenario requires a centralized package manager.
Targeting for .NET 4.8 (highest version currently supported by MIM) gave us the DLLs in the bin directory and set binding redirects in the config file.
That said, the System.Buffers.DLL version issue only went away because the .NET 4.8 dependencies were defined correctly. The Microsoft.Extensions.Configuration.Json .nuspec indicates a different assembly version than the dll that gets downloaded when compiling for .NET Standard 2.0. I don't know if that's an issue with the references when the .NET developers compiled the nuget package or an unavoidable artifact of nuget packaging itself.
My application references the Sage50 SDK and I need to support multiple versions of the SDK.
In Visual Studio each version of the SDK has its own project and has the SDK DLL's referenced.
But when I build the solution the DLL's overwrite eachother and only 1 version remains.
I can't rename the DLL's because the SDK loads other DLL's by name and will error out when they are renamed. And they are signed.
How would I go about a situation like this?
Make each project uses a 'strong' reference to those different sage SDK assemblies. That is, make sure it specifies a version, culture, and token etc... Nothing worse than a versionless, sloppy reference.
You will have to output your project DLL's to separate locations. Because the build will copy all dependencies to the output folder.
Because of #2, you will have to dynamically load your assemblies in your application. (i.e. Assembly.load(...))
I have a Class library project. I am installing this dll produced by the project into the GAC by the command "gacutil /i [Path of the dll]". This dll is used by a windows application. When windows application runs, it successfully accesses the functions and properties of the dll.
Now I have made some changes to the dll. I have uninstalled the original dll from the GAC and will install the newer dll with the required changes. Now when the windows application uses this dll, the new changes from the dll are not getting reflected in the application. The new changes should reflect into the application as I installed the new dll into the GAC.
The Name, version and Public key token is the same for both dlls. I think it won't matter as the i have uninstalled the previous dll and installed the new dll into the GAC.
Am I doing something wrong?? Please suggest a solution.
Thanks and Regards,
Mayur Mahajan
I would suggest for debugging purposes that you version your dll, then print the version to your application to be sure its being updated. Include the System.Reflection namespace and the code would run look like the following:
Assembly assembly = Assembly.LoadFrom("unknown.dll");
label.Text = assembly.GetName().Version.ToString();
In my web and worker roles, I am referencing an alternative version of a core framework DLL. The file is marked Copy Local. Visual Studio shows the correct version in as a project reference. When compiling the project, the bin directory also contains the correct version.
However, when I ask Visual Studio to create an Azure package, the package (and the csx folder created during packaging) contains the wrong (original) DLL for the Worker role only. The Web role has the correct DLL. This does not occur if I manually use cspack, but that's not really a desirable way to package.
What could cause Visual Studio to compile with the correct reference DLL but bundle the wrong one?
Additional info:
When I run msbuild to do the packaging instead of Visual Studio, I see the following two lines:
Copying file from "C:\Users\bytenik\Dropbox\Treadmarks\lib\EntityFramework\System.Data.Entity.dll" to "C:\Users\bytenik\Dropbox\Treadmarks\src\Azure\obj\Debug\Worker\System.Data.Entity.dll".
Copying file from "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.Entity.dll" to "C:\Users\bytenik\Dropbox\Treadmarks\src\Azure\obj\Debug\Worker\System.Data.Entity.dll".
So, it seems to copy my reference, and then copy over it with the system reference.
Note: I'm well aware that the entire concept of replacing a .NET CLR DLL is a huge hack. When .NET 4.5 comes out supporting the feature I need, this will all be stripped out. In the meantime, I need to be able to continue development.
This is a replacement to question "Azure References Incorrect DLL", which was actually factually incorrect and lead to answers that were valid, but did not solve my problem.
Even if a Visual Studio project has a reference to a local and/or modified copy of a assembly that is in the GAC, it will be used during the compilation, but at runtime, the CLR will always load the assembly from the GAC, even if it is sitting right there in the same directory as your application.
So the solution does not involve figuring out a clever way to pack or deploy the modified assembly, but figuring out a way of making the CLR actually load it if it's there.
Two possible solutions:
1) Use a role startup task and an installation project to deploy the modified version of the assembly in the production server's GAC.
2) Remove the signature of the assembly and make sure all references are made to this version without the signature. Beware other assemblies that may be referencing the original signed version and will try to load it from the GAC.
For more details and links see How to prevent a .NET application to use an assembly from the GAC?