We are developing an add-in for Autodesk Inventor. Our software is a bunch of dll assemblies loaded into Inventor at runtime. We have decided to use the Microsoft Enterprise Library 5.0 for logging and exception handling.
Now we have a problem, because it turns out Inventor 2013 uses Enterprise Library 4.1. When our add-in is loading, it fails to load the proper version of an assembly, because Inventor already has an older version in its Bin directory.
Options we have considered so far:
During deployment of our product, overwrite the old libraries in Inventor's Bin folder
Use EL 4.1 in our assemblies
Both are bad and I'm running out of ideas, so I'm asking for help.
Option 1 raises this question: is the Enterprise Library backwards compatible and will replacing those DLL's in the Bin folder cause problems? I have tried it, Inventor doesn't complain and works as expected (haven't checked the EL functionality).
Option 2 makes us use the older version and binds us to the version Autodesk is using, so we would have to watch when they upgrade, especially when they release a new version of Inventor.
What is the best practice in this scenario?
UPDATE:
We solved this by just putting the newer version of Enterprise Library in GAC. I think what happened here was that .NET tried loading the older version first (because it was higher in assembly search order) and after failing never went any further to look for the proper version. When in GAC, it correctly resolves.
From what I can see, a reasonable solution would be to embed the assemblies and access them using the ResourceManager class, this would allow you to use the newer versions whilst maintaining the parent projects logging mechanism.
You might find this question useful:
Embedding assemblies inside another assembly
Related
.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.
I cannot find in the documentation a way to start a XSocket server without using the PlugIn Framework.
I have a very easy library which contains its own controllers (located in the library itself) and which references XSockets.
I don't really need the PlugIn Framework and it is disturbing me because my library is located in a binaries folder with a number of other components that I don't manage. The PlugIn Framework is not working properly in such a complex environment and I'm quite sure it has to be possible to get an instance of the server singleton (new() is not working) without having to use:
server = XSockets.Plugin.Framework.Composable.GetExport<IXSocketServerContainer>();
thanks for your help.
My guess is this.
You have a non .net assembly in your bin folder. In XSocket plugin framwork version 1.1 there was a bug throwing an exception when trying to load an non .net assembly.
This issue is fixed in 1.3 (current version) and upgrading to XSockets 3.0.3 should take care of this issue.
I am upgrading an application and running into some issues with it.
Now the old application was version 1.0 and loading a depedency assembly A at version 2.1.1 The assembly is present in application local directory.
I am upgrading the new application to version 2.0 that will load assembly A version 1.0.1 which is present in its application local directory. I've checked application references using ISpy and confirmed the new application references A version 1.0.1
But when I start the new application (v 2.0), it is still trying to load assembly version 2.1.1 and failing. I checked the app.config, machine.config and GAC and there is no redirection for version of assembly A. I also checked fusion log files but don't see any redirection. All I see is the fusion log is that application prebinds A at version 2.1.1 and hence fails to set up the assembly present in its local directory.
Is there something I am missing here? What could be the possible reasons for application still referencing the older assembly at runtime?
Update: Using some tools, I realized the the older assembly is being referenced from a native DLL that is referenced by my application, but I don't know which third party DLL is that, and the application loads a ton of them. The fusion log confirms it by logging "Calling assembly : (Unknown)." for the missing assembly.
Now my next step is to find which dll is referencing the wrong assembly and fix that. Now the problem is that ILSpy tool doesn't show the native DLLs references, and DLLDepends tool does not show the assemblies references, so I am not able to link the two.
thanks
Since the library your trying to reference is supposed to be apart of the GAC; you may want to try:
Control Panel
Small Icons(Administrative Tools)
Event Viewer
Application
Windows itself should throw an exception with some particular details it's attempting to reference when it has an error. Especially if it's apart of the GAC. It was more helpful for me to hone in mscoree.dll and mscorelib.dll libraries fairly easy. Granted those clients that I used that for had corrupt framework; but Event Viewer told me the exact library that it had an issue with.
You may want to try that. Not sure which library; but keep in mind this is usually beneficial to libraries that are found within the %windir%/Assembly folder. Hope that helps.
I'm new in monodevelop and I have a question.
I have some assemblies developed in Visual Studio 2010 in C# and I would like to use them with monotouch in Mac, my question is: do I have to use the source and generate the assemblies with monodevelop in Mac or just I need the assemblies and add them to my solution as a reference?
The framework profile used by MonoTouch was originally based on the Silverlight profile (aka 2.1) and was updated to include some, but not all, of the new API provided by the .NET framework 4.0.
As such you might be able to reuse assemblies, without recompiling them. That will depends if all the API are available, if you refer to assemblies not available in MonoTouch, under what profile (3.5 or 4.0) you're building the code...
However things would be a lot easier if you have the source code and are able to re-compile it inside MonoDevelop. That would provide you with debugging symbols (the .mdb files) also also catch, at compile time (not at run time), and fix code using any missing API (from MonoTouch).
You should be able to use the same assemblies as they are (no need for a recompile). If the assemblies depend on other nonstandard assemblies it might get tricky and you may have to deploy other assemblies along side the ones you want and then that may cause it's own problems if they are not open source or licenses are required to redistribute, etc.. Give it a shot, see what happens.
I am creating a Class LLibrary in c# by using microsoft provided Dll's.
Now i want to statically add those Microsoft provided libraries to My Dll.How can i do this.
I have simply added a reference to those Microsoft provided Dlls and creating My Dll? Is it fine or not?
if Microsoft provided dll is not available on other machine then my Dll may fails i need to add the libraries statically??
How can i do this??
There's no such thing as statically linking to another assembly in .NET. There are some third party products such as .NET linker that merge assemblies into one but they are unsupported.
If you have the redistribution license for that library, you can ship a copy along with your assembly. In Visual Studio you can make this happen by setting "Copy Local" to "True" in the properties window for that assembly reference.
See discussion here and read the comments -- Jeff does provide a way.
http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
If the dll is not available at execution time; yes it will fail. However:
many Microsoft dlls are pre-installed with .NET (caveat: "client profile")
many of the Microsoft dlls are redistributable; so you can include them with your package
There isn't a linker provided in the core framework, although ILMerge may be useful.
Its not very clear what you want to achieve but it seems you are concerned that your class lib will work on some other machine or not. The thing is that the .Net framework is a free redistributable which should be installed if not present on the target machine. With the .Net framework already installed on a machine, there should be no problem as such.
Static linking as such does not make sense in .Net other that adding an assembly reference to your project. Hope it helps