Ambiguous call when using certain libraries at once - c#

In my Xamarin project I'm using ReactiveUI and Firebase.Xamarin. When these two libraries are being used at once, any attempt to use System.Reactive.Linq.Observable extension methods such as Where or Select results in compile time error:
The call is ambiguous between the following methods or properties: 'System.Reactive.Linq.Observable.Where(System.IObservable, System.Func)' and 'System.Reactive.Linq.Observable.Where(System.IObservable, System.Func)'
I presume this is being caused by both of these libraries defining/referencing the same methods in same namespaces. How can I fix that?

It is likely that you are loading more than one version of the assembly that defines that namespace. It may be that the assemblies that you refer to load a common dependency. If they load different versions of that assembly you would get this error.
Ensure that you are using versions of the two libraries that depend on the same version of the dependant assembly.

Firebase.Xamarin is no longer maintained so if I wanted to follow #PhilipSmith advice I would have to use ReactiveUI version that is over 2 years old. I didn't wanted to do it so I decided to clone Firebase.Xamarin since its OSS and add it to my solution as another project with intention to alter the ReactiveUI version it was referencing. But when I added is as a referenced project the error disappeared.

Related

Decompiling .NET assemblies only shows throw null; [duplicate]

I have a project that uses System.Runtime.Serialization assembly. I am using the type DataContractSerializer from that assembly, but I have a problem.
There are two assemblies:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Runtime.Serialization.dll
C:\Windows\Microsoft.net\Framework\v4.0.30319\System.Runtime.Serialization.dll
Both of them have the same version - v4.0.30319. The first one have 429kb size, and the second one 1037kb. I used reflector to see the list of classes, and the first one doesn't have the class that I need (DataContractSerializerSettings). However, the second one does have it.
Why are there some big difference in size and classes for that assembly? Will it be ok, if I use the second one, instead of the first?
.NET version 4.0 made a big change in the way framework reference assemblies are done. Previously, the reference assembly was a simple copy of the runtime assembly, the one stored in the GAC. That however caused some painful problems. Notable is the WaitHandle.WaitOne(int) overload, it was added in the .NET 2.0 Service Pack 2 update (aka .NET 3.5). Programmers used it without noticing that it was an added method, the mscorlib assembly version number was still 2.0.0.0. But then discovered their program failed when running on an unpatched version of .NET 2.0. Very nasty kaboom, MissingMethodException without a hint why such a common method could be missing.
To prevent this kind of breakage, the .NET 4.0 reference assemblies are kept separate, in the "%programfiles%\Reference Assemblies" directory as you found out. And they are special assemblies, they only contain the metadata with all the IL stripped out. Which is why the assembly is so much smaller.
Microsoft now can improve the .NET 4 code and add public classes and methods without causing this kind of breakage. And have done so profusely, updates 4.01, 4.02 and 4.03 have shipped since the original 4.0 release.
The reason you are having trouble with the DataContractSerializerSetting class is thus easily explained, it just doesn't appear in the reference assembly. It got added, probably in one of those incremental updates. And you should not try, your program will break on a machine that doesn't have the update. You should wait until .NET 4.5, the version that added it to the reference assembly. You can invoke DLL Hell if you really want to.

How to add reference to two versions of the same api in visual studio/c#

I have a project that depends on an external program, this external program has an API, well actually it has about 17 different APIs all slightly different for version 2000-2017. Now within these 17 versions I want to support about 5 of them. (2012-2017) but there are several features that were in 2012 that have since been renamed in 2017.
Now the good news is that I can trivially determine which version of the program a given user is using and any shared functions (90%+) can be called using a reference to a different version of the API. However I need some of the remaining 10% of the features. So I need to include the references to multiple APIs so that my program will compile and then at runtime pick which version it receives.
Now what I tried is to go into the visual studio (2015 community version), and add a reference to several of thes. However the moment I try adding in a second reference I get a error message: a reference to [API.dll] could not be added a reference to the component [API.dll] already exists in project..
I would like the method use to be such that if a function with a given name exists in one of the versions it should bind to that one and if a given function name exists in multiple APIs then it should bind to the latest. Any idea how to do this? Maybe something using the extern alias keyword?
I looked at How to reference two versions of an API? and the accepted answer won' t work but the second answer might, anyone capable of explaining if that one will work and if so how to do it correctly?
Basically, it is not allowed to add multiple references with the same name.
If you are the assembly owner, you have to change the file name in the manifest to generate DLLs with different names.
You can also manage the assembly version in the configuration file or load at runtime.
My suggestion is to merge all the DLLs into a single file. You can use ILMerge to do this.

How to solve the "System.Tuple defined multiple times issue"?

I work on a project target WP 7.5 and above, I add a packages using the Nuget in VS 2012 which name is Coding4fun(Controls).
After that, the IDE give me a warning,
Warning 1 The predefined type 'System.Tuple' is defined in multiple
assemblies in the global alias; using definition from
'c:\Users\Gao\Documents\Visual Studio
2012\Projects\TFSGit\xicihutong\packages\Coding4Fun.Toolkit.Controls.2.0.5\lib\wp71\Coding4Fun.Toolkit.Controls.dll' C:\Users\Gao\Documents\Visual
Studio 2012\Projects\TFSGit\xicihutong\xicihutong\CSC xicihutong
The app runs OK, but how to solve this warning?
From Compiler Warning (level 1) CS1685
This error occurs when a predefined system type such as System.Tuple
is found in two assemblies. One way this can happen is if you are
referencing mscorlib from two different places, such as trying to run
the.Net Framework versions 1.0 and 1.1 side-by-side.
The compiler will use the definition from only one of the assemblies.
This problem occurs probably System.Tuple is defined in two different assemblies. Probably your Coding4Fun.Toolkit.Controls.dll has too besides mscorlib.dll.
If you want to look them both you can check them;
Get a decompiler like ILSpy or Jetbrains dotPeek.
Add all 3rd party assemblies.
Search for System.Tuple
But how to solve this warning?
You can define your 3rd party assemblies reference some aliases. You can follow in your project
Reference -> Properties -> Aliases ->
And change "global" to something different.
Check out for information extern alias (C# Reference)
Newer version of c4f toolkit has resolved this issue.

How do I create and use a .NET metadata-only 'Reference Assembly'?

Since version 3.0, .NET installs a bunch of different 'reference assemblies' under C:\Program Files\Reference Assemblies\Microsoft...., to support different profiles (say .NET 3.5 client profile, Silverlight profile). Each of these is a proper .NET assembly that contains only metadata - no IL code - and each assembly is marked with the ReferenceAssemblyAttribute. The metadata is restricted to those types and member available under the applicable profile - that's how intellisense shows a restricted set of types and members. The reference assemblies are not used at runtime.
I learnt a bit about it from this blog post.
I'd like to create and use such a reference assembly for my library.
How do I create a metadata-only assembly - is there some compiler flag or ildasm post-processor?
Are there attributes that control which types are exported to different 'profiles'?
How does the reference assembly resolution at runtime - if I had the reference assembly present in my application directory instead of the 'real' assembly, and not in the GAC at all, would probing continue and my AssemblyResolve event fire so that I can supply the actual assembly at runtime?
Any ideas or pointers to where I could learn more about this would be greatly appreciated.
Update: Looking around a bit, I see the .NET 3.0 'reference assemblies' do seem to have some code, and the Reference Assembly attribute was only added in .NET 4.0. So the behaviour might have changed a bit with the new runtime.
Why? For my Excel-DNA ( http://exceldna.codeplex.com ) add-in library, I create single-file .xll add-in by packing the referenced assemblies into the .xll file as resources. The packed assemblies include the user's add-in code, as well as the Excel-DNA managed library (which might be referenced by the user's assembly).
It sounds rather complicated, but works wonderfully well most of the time - the add-in is a single small file, so no installation of distribution issues. I run into (not unexpected) problems because of different versions - if there is an old version of the Excel-DNA managed library as a file, the runtime will load that instead of the packed one (I never get a chance to interfere with the loading).
I hope to make a reference assembly for my Excel-DNA managed part that users can point to when compiling their add-ins. But if they mistakenly have a version of this assembly at runtime, the runtime should fail to load it, and give me a chance to load the real assembly from resources.
To create a reference assembly, you would add this line to your AssemblyInfo.cs file:
[assembly: ReferenceAssembly]
To load others, you can reference them as usual from your VisualStudio project references, or dynamically at runtime using:
Assembly.ReflectionOnlyLoad()
or
Assembly.ReflectionOnlyLoadFrom()
If you have added a reference to a metadata/reference assembly using VisualStudio, then intellisense and building your project will work just fine, however if you try to execute your application against one, you will get an error:
System.BadImageFormatException: Cannot load a reference assembly for execution.
So the expectation is that at runtime you would substitute in a real assembly that has the same metadata signature.
If you have loaded an assembly dynamically with Assembly.ReflectionOnlyLoad() then you can only do all the reflection operations against it (read the types, methods, properties, attributes, etc, but can not dynamically invoke any of them).
I am curious as to what your use case is for creating a metadata-only assembly. I've never had to do that before, and would love to know if you have found some interesting use for them...
If you are still interested in this possibility, I've made a fork of the il-repack project based on Mono.Cecil which accepts a "/meta" command line argument to generate a metadata only assembly for the public and protected types.
https://github.com/KarimLUCCIN/il-repack/tree/xna
(I tried it on the full XNA Framework and its working afaik ...)
Yes, this is new for .NET 4.0. I'm fairly sure this was done to avoid the nasty versioning problems in the .NET 2.0 service packs. Best example is the WaitHandle.WaitOne(int) overload, added and documented in SP2. A popular overload because it avoids having to guess at the proper value for *exitContext" in the WaitOne(int, bool) overload. Problem is, the program bombs when it is run on a version of 2.0 that's older than SP2. Not a happy diagnostic either. Isolating the reference assemblies ensures that this can't happen again.
I think those reference assemblies were created by starting from a copy of the compiled assemblies (like it was done in previous versions) and running them through a tool that strips the IL from the assembly. That tool is however not available to us, nothing in the bin/netfx 4.0 tools Windows 7.1 SDK subdirectory that could do this. Not exactly a tool that gets used often so it is probably not production quality :)
You might have luck with the Cecil Library (from Mono); I think the implementation allows ILMerge functionality, it might just as well write metadata only assemblies.
I have scanned the code base (documentation is sparse), but haven't found any obvious clues yet...
YYMV

"Missing compiler required member" error being thrown multiple times with almost no changes to code

Today after deploying some changes to a C# MVC site that I run, I went back to make some more modifications and came across this error:
Missing compiler required member System.Runtime.CompilerServices.ExtensionAttribute..ctor
The error is a bit vague (other than it's description, obviously) as it doesn't give me a file, line, or column to reference, only the project. Also, it throws the error a total of 20 times. I only made three changes to the code between the time I deployed (it was completely functional at that time) and now. I reverted my changes and it is still throwing the same error which makes no sense to me.
I haven't found a lot of information on this error on SO or Google, other than this guys solution and a couple references to some Mono project errors (I'm not using Mono). The solution the guy above gives requires adding a class definition that will allow the compiler to resolve the reference. I don't particularly want to do this because I haven't needed to do it up until this point and it will just muddy my code.
Just curious if anyone has run across this before.
In my case it was because the project was not referencing Microsoft.CSharp. Once I added a reference to that assembly, it compiled just fine.
I don't know if anyone else has experienced this, but I suddenly ran into this error after adding some code utilizing dynamic types and incorporating WebAPI into a project that originated as a TypeScript application in VS2013. Simply adding a reference to Microsoft.CSharp resolved my issue.
Hope this helps someone else.
This error usually means either your project is compiling against .NET 2.0 or you aren't referencing the correct version of System.Core.dll
For a near duplicate question, see Error when using extension methods in C#
I ran into this situation as well today. In my case I was referencing the Newton.Json.Net dll v3.5 in my .NET 4.0 application. I realized that I wasnt even using this library, thus once I removed it from my references, it no longer gave me the compiler error.
Problem solved!!!
The actual error comes from the fact that your 2.0 assembly that causes the error contains this code:
namespace System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attribute { }
}
The Code Above allows the .NET 2.0 Assembly to use extension methods (see Using extension methods in .NET 2.0?). While it confuses the compiler if you target .NET 4.0 and reference a 2.0 Assembly (containing above code) as the mscorlib.dll(4.0) contains the same class in the same namespace.
I fixed this
by compiling the original 2.0 assembly again without the attribute targeting 4.0
by removing the assembly (obviously)
by adding a third Extension Attribute in the target you compile (it seems to overrule the referenced definitions)
Writing this code somewhere in your project may solve your problem. It works for me
namespace System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attribute { }
}
Probably you use dynamic keyword In .NetStandard Class library project. If so, you need to add a reference to Microsoft.CSharp library in the project. Hope it will resolve your problem.
NLog.dll 2.0 referenced from a .NET 4.0 project can cause this too.
I don't have a correct solution, but I'll add my data point:
In my case the error is caused by referencing GoogleSearchAPINet20
Here is what happens:
I close the solution that builds
I open the solution again. It still builds
As soon as I make any change and try to build, I get 19 "Missing compiler required member ..." errors
I remove the reference to GoogleSearchAPINet20
I add back the reference to GoogleSearchAPINet20
I build the solution. It builds without errors
I can now make code changes, build or perform any other actions with solution correctly as long as my Visual Studio is open
I close Visual Studio
Repeat from step one
I'm not referencing System.Core.dll in my solution at all and my target framework is .NET 4.
I'm a bit annoyed at this point ...
Got this error when trying to use async Tasks against .NET 4.0. Updating Target Framework to 4.5.2 fixed the problem.
I hit the same set of exceptions after I added some async methods to a winforms project. I needed to bump my .NET version from 4 to 4.5
For me, the problem occure when I add asynchronous method with async Task await in my .net4.0 project !
With previous versions of the .NET-Framework 4.5, you must install this package:
Install-package Microsoft.Bcl.Async –pre
or
Install-Package Microsoft.CompilerServices.AsyncTargetingPack
more info on Nuget or Nuget

Categories

Resources