Member access call does not compile but static call does - c#

So today I faced interesting problem while trying to build our company solution and I wanted to ask you guys do you know why is this happening. I've been told that it might be from my machine/visual studio because other people did not have same problem.
So we have a method in project A:
private static string RpcRoutingKeyNamingConvention(Type messageType, ITypeNameSerializer typeNameSerializer)
{
string queueName = typeNameSerializer.Serialize(messageType);
return messageType.GetAttribute<GlobalRPCRequest>() != null || AvailabilityZone == null
? queueName
: queueName + "_" + AvailabilityZone;
}
where GetAttribute<GlobalRPCRequest>() is defined in public static class ReflectionHelpers
public static TAttribute GetAttribute<TAttribute>(this Type type) where TAttribute : Attribute;
then we have project B which have method:
public static string GetAttribute(this XElement node, string name)
{
var xa = node.Attribute(name);
return xa != null ? xa.Value : "";
}
I have to point out that we have reference to project B in project A.
Now what happens is that when I try to build I get compile error:
Error 966 The type 'System.Xml.Linq.XElement' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. D:\Repositories\website\website\submodules\core\src\A\Extensions\Extensions.cs 37 13 A
Whats happening is that compiler thinks that I am actually using GetAttribute method from project B(in my opinion!). Why this is happening? Since when I try to navigate to GetAttribute VS leads me to the right method (the one that is in ReflectionHelpers).
Could it be because of the reflection? NOTE: I fixed this issue by calling the method statically or adding reference to System.Xml.Linq in my project A, but I am curious of the strange behavior of VS/syntax-checking feature.

It's a guess, but I think your function:
private static string RpcRoutingKeyNamingConvention(Type messageType, ITypeNameSerializer typeNameSerializer) does not match your helper method signature because you try returning a string:
public static TAttribute GetAttribute<TAttribute>(this Type type) where TAttribute : Attribute; which expects a TAttribute return type.
Maybe, you can try modifiying your function RpcRoutingKeyNamingConvention to return GlobalRPCRequest and check if the compiler continues to go crazy.

Visual Studio gets confused all the times! I tried to reproduce the scenario in my VS 2015 (.NET 4.6) and it compiles just fine. I didn't have to add reference to System.Xml.Linq in my Project A.
My guess is that it might be a cache issue. You might want to try this:
Remove reference to Project B
Clean then rebuild both solutions
Add the reference back
Rebuild and voila!! Well.. hopefully
Hope it helps, let me know :)

I guess that's going on:
- B has reference to System.Xml.Linq
- B is built without a problem.
- You are referencing B in A
- A hasn't got a reference to System.Xml.Linq
- A seem to consume the function defined in B
- When you try to build project A, it produces that error
Am I right?
If that's the case, it is totally normal. Because a project which consumes a reference (A) must have a reference to what is referenced (System.Xml.Linq) by what it references (B).
Think like this: When you try to add a nuget package to your project if it has a dependency, nuget will install it too. Why? Because of this situation.
This is completely normal if I understand your answer correctly.

Related

System.MissingMethodException after adding a project reference (without using the reference)

I have encountered a strange error that is unexplainable to me.
I have a .NET 6 class library project (A) that has the function:
public async Task ImportDeliveries()
{
try
{
var csvFileProcessor = new CsvFileProcessor();
await csvFileProcessor.ProcessAllAsync(_DeliveryImporter.ImportAsync).ConfigureAwait(true);
}
catch (Exception ex)
{
_TelemetryClient.TrackException(ex);
}
}
It works fine. However, as soon as I add the project reference of another .NET 6 class library (B) to the project, without changing anything else, the function
await csvFileProcessor.ProcessAllAsync(_DeliveryImporter.ImportAsync).ConfigureAwait(true);
fails and throws the following exception:
System.MissingMethodException: 'Method not found: 'System.Threading.Tasks.Task BlobStorageHelper.BlobStorageFolder.MoveAsync(Microsoft.Azure.Storage.Blob.CloudBlockBlob, BlobStorageHelper.BlobStorageFolder)'.'
Can this be caused because (B) contains certain nuget packages?
This behavior is very counterintuitive to me, and I'm not sure where to start looking.
This is probably caused by:
Your project, A, referencing a class library C, in which CsvFileProcessor and BlobStorageHelper.BlobStorageFolder are defined (the latter could also be in a transitive dependency, D).
Project B also references class library C (and/or D), but a different version.
Someone modified, added or removed System.Threading.Tasks.Task BlobStorageHelper.BlobStorageFolder.MoveAsync(Microsoft.Azure.Storage.Blob.CloudBlockBlob, BlobStorageHelper.BlobStorageFolder) in some version of C or D.
You're not properly implementing Semantic Versioning within C or D, so MSBuild is restoring a version of C or D that doesn't contain the required method.
Hence the error.
Takeaway: changing a signature or return type is breaking the ABI (application binary interface), requiring a major version update.
To fix this, you could revert the signature or return type change, and add an overload instead.

Unable to compile code output because of some reference assembly goofups

My issue goes like this:
There is a project called myframework. It has some extension methods defined in it as follows:
namespace myframework
{
public static class Helpers
{
public static bool ContainsAll(this string obj, string[])
{
return true;
}
}
}
It also has some other stuff like interfaces, etc, etc.
There is a second class I generate via System.CodeDom classes. The generated output is somewhat like this:
using myframework;
public class A: IMyFrameworkInterface
{
public void foo()
{
string s ="HELLO";
if(s.ContainsAll(some_arr))
return;
}
//More methods defined...
}
The compiler options I pass which is created prior to the actual compile call references the correct assemblies
var cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("myframework.dll");
The code compilation modules are written in a different project. The particular class responsible for this also nicely gives us access to a list of CompilerError object via which we can learn the result of compilation.
Issue1: When I tried this in an asp.net project the compiler threw error saying it could not find metadata file myframework.dll (despite it being referenced in the project).
Issue2: When I tried it with a windows forms project. It gave a different error. This time saying that string does not contain definition for ContainsAll()
How to solve these two specific problems?
Found out the answer to this after a bit digging up. I was using .net framework 3.5. The codedom compiler apis targets v2.0 of the framework by default. Hence, you have to manually specify the correct framework:
var cp = new CompilerParameters(
new Dictionary<string,string>() { {"CompilerVersion", "v3.5"} });
For the compilation to work within an asp.net environment you'd have to actually point the references to the correct location. Hence you'd have to do something like follows:
cp.ReferencedAssemblies.Add(
HttpContext.Current.Server.MapPath(
"bin\\myframework.dll"));
My references:
http://blogs.msdn.com/b/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx
.Net 3.5 CodeDom Compiler generating odd errors
And comments in the question's post. :)

Having trouble getting started with Moq and Nunit

Banging my head against a wall trying to get a really simple testing scenario working.
I'm sure I'm missing something really simple!
Whatever I do, I seem to get the following error from the NUnit gui when running a test against my DLL:
System.TypeLoadException : Type 'Castle.Proxies.ITestProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is attempting to implement an inaccessible interface.
Now I've seen reference to this error in heaps of places when looking in Stack Overflow and elsewhere, but the solution I keep finding doesn't seem to help. And I'm not even using an internal interface at this stage! The solution I see around the place is too put the following line in AssemblyInfo.cs
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
I'm using:
Visual Studio 2010 Professional
c# 4.0
Moq 4.10810.8 Beta (bin deployed)
NUnit 2.5.5 (Installed in GAC)
To recreate this error, all I need to do is:
Create a new class library project
Reference Moq and Unit (as above)
Create an interface. I've called my interface ITest, made it public, and it has one method which is 'string TestMethod();'. Am doing this in the local project for simplicity.
Create a class called 'Testing', decorated with [TextFixture] and a test method called 'TestMethod' decorated with [Test]
Build the project, then run NUnit against the resulting dll in the Debug folder.
Here's the contents of my test class
namespace MoqTest {
[TestFixture]
public class Testing {
[Test]
public void TestMethod() {
var testMock = new Mock<ITest>();
testMock.Setup(x => x.TestMethod()).Returns("String val");
var xyz = testMock.Object;
Assert.AreEqual(1, 1);
}
}
}
---- UPDATE ---
After changing Moq version from 4.10810.8 to 4.0.10501.6 everything works fine!
The following test passes for me:
public interface ITest { string TestMethod(); }
public class Testing
{
[Test]
public void TestMethod()
{
var testMock = new Mock<ITest>();
testMock.Setup(x => x.TestMethod()).Returns("String val");
var xyz = testMock.Object;
Assert.AreEqual(1, 1);
}
}
If your interface is public and in the same assembly, there really should be no problem. I suspect that you just missed an accessibility keyword somewhere, as a non-public interface does provoke a runtime error because the proxying assembly will be unable to instantiate a type based on it.
Probably the best thing to do is start with the code I've provided and change one thing at a time until it matches your failing code. If you run your test in between each change, I presume you'll find what was missing.
If you do go back to an internal interface, note that your InternalsVisibleTo statement must be in the same assembly as your internal interface, not your test assembly. Also note that if your assembly is strongly named you may need to add a public key fingerprint to your InternalsVisibleTo statement as described in MSDN.
Yeah I had the same issue with Moq.4.0.10810.8 for NET40... When I downgraded to version 4.0.10531.7 everything went green again!
I'm using 4.10.1 now, and I got this same issue. I tried downgrading to 4.10.0, but to no avail.
I finally found that, although the interface I was using was marked as public, it was in a class without a modifier. I found 2 things got it to work:
1) Pull the interface outside of the class. Because the class was no longer making the interface internal, it became accessible to the assembly.
2) Mark the class public. With all parts of the path to the interface being marked public, the assembly had no trouble accessing.
These strategies worked in both 4.10.0 and 4.10.1.

Type.IsSubclassOf() doesn't work across AppDomains?

I'm having some problems with the following code:
private class ClientPluginLoader : MarshalByRefObject
{
public bool IsPluginAssembly(string filename)
{
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomainReflectionOnlyAssemblyResolve);
Assembly asm = Assembly.ReflectionOnlyLoadFrom(filename);
Type[] types = asm.GetTypes();
foreach (Type type in types)
{
if (type.IsSubclassOf(typeof(ClientPlugin)))
{
return true;
}
}
return false;
}
}
The code is called via a proxy that I've created through my custom app domain's CreateInstanceFromAndUnwrap(). This means that IsPluginAssembly() is executed in the context of my custom app domain.
The problem is that the call to IsSubclassOf() always returns false, even though it should IMHO return true. The "type" in question really does inherit from ClientPlugin - there's no doubt about that.
ClientPlugin is defined in a different private assembly, which I'm resolving manually, as evident in the code fragment above.
I've put a breakpoint on the if (type.IsSubclassOf(...)) line and confirmed this expression to be false:
type.BaseType == typeof(ClientPlugin)
On the other hand, this expression is true:
type.BaseType.FullName == typeof(ClientPlugin).FullName
How is this possible? What's going on?
UPDATE: Kent Boogaart pointed me to the right direction. I searched the web a bit more and run into this blog post. It seems I'll have to resolve my Load/LoadFrom/ReflectionOnlyLoadFrom conflicts in order to make this work.
This is due to loading into a different context. How you load an assembly (Load / LoadFrom / ReflectionOnlyLoad) determines which context it is loaded into. This simple example also demonstrates the problem:
using System;
using System.Reflection;
class Foo
{
public static void Main()
{
var type = typeof(Foo);
var reflectionLoadType = Assembly.ReflectionOnlyLoad("ConsoleApplication1").GetType("Foo");
Console.WriteLine(type == reflectionLoadType); //false
Console.WriteLine(type.Equals(reflectionLoadType)); //false
Console.WriteLine("DONE");
Console.ReadKey();
}
}
See here for more info.
I've had a similar problem. I also had this architecture - a .DLL that contains ClientPlugin base class; several plugins which reference this .DLL; and a main application, which also references this .DLL. The problem was that the .DLL with the ClientPlugin base class was copied in two folders - both the Plugins folder, and the main application folder. Thus it got loaded twice in my AppDomain (plugins also loaded it indirectly). And when the main application tried to do reflection type magic, it failed, because there were two instances of the ClientPlugin type.
Although I don't think this is exactly your case, there still is a lesson to learn here - if a .DLL gets loaded twice, the types will also be duplicated. In your case I would suspect either separate AppDomains, or the "ReflectionOnlyLoad", because the .DLL is then loaded somehow differently.

F# declared namespace is not available in the c# project or visible through the object browser

F# declared namespace is not available in the c# project or visible through the object browser.
I have built a normal F# library project, but even after i build the project and reference it to my C# project, I am unable to access the desired namespace.
I am also unable to see it in the object browser, i get an error telling me that it has not been built. I am running on the september release can someone point out my error ?
F# Version 1.9.6.0
(6) Edit : Referencing the dll directly has fixed my problem, referencing the project allows me to compile but the intellisence does not work. When the dll is directly referenced the intellisence works perfectly.
This is the code found in the .fs file
#light
namespace Soilsiu.Core
module public Process =
open System.Xml.Linq
let private xname (tag:string) = XName.Get(tag)
let private tagUrl (tag:XElement) = let attribute = tag.Attribute(xname "href")
attribute.Value
let Bookmarks(xmlFile:string) =
let xml = XDocument.Load(xmlFile)
xml.Elements <| xname "A" |> Seq.map(tagUrl)
let PrintBookmarks (xmlFile:string) =
let list = Bookmarks(xmlFile)
list |> Seq.iter(fun u -> printfn "%s" u)
(5) Edit : Could ReSharper 4.0 be the problem?
(4) Edit : When i say the Object browser is unable to read the resulting assembly, i mean that when I try to open the assembly in the object browser i get an error telling me the project has not yet been built. yet again i can read the assembly using reflector.
(3) Edit : Reflector can Disassemble the dll but the Object Browser is unable to read it.
(2) Edit : I have Upgraded my F# version to 1.9.6.2 and still the same consequence
(1) Edit : I was able to Disassemble the dll to C# I get : (Everything seems to be fine here)
namespace Soilsiu.Core
{
[CompilationMapping(7)]
public static class Crawler
[CompilationMapping(7)]
public static class Process
}
[CompilationMapping(7)]
public static class Process
{
// Methods
static Process();
public static IEnumerable<string> Bookmarks(string xmlFile);
public static void PrintBookmarks(string xmlFile);
internal static string tagUrl(XElement tag);
internal static XName xname(string tag);
// Nested Types
[Serializable]
internal class clo#13 : FastFunc<XElement, string>
{
// Methods
public clo#13();
public override string Invoke(XElement tag#9);
}
[Serializable]
internal class clo#17 : FastFunc<string, Unit>
{
// Methods
public clo#17();
public override Unit Invoke(string u);
}
}
What if you reference the produced DLL directly (i.e., not via a project reference, but via a file reference)?
Maybe IntelliSense is just messed up? What compiler error do you get when you try to use it in C#? When you say "the object browser is unable to read it" what does that mean?
For what it's worth, I added this to a F# library project, referenced it (project) from a C# console app, and was able to use it. IntelliSense did not work at first though. (Had to rebuild.)
If you can make a solid repro, I'd suggest emailing it to F# bugs alias (fsbugs).
I tried the same thing. It looks as if Visual Studio and Resharper 4.0 doesn't understand F# for some reason. If you ignore the sea of red text and the lack of intellisense, it will compile fine.
Try
Make sure that C# project is targeted FULL .NET (NOT Client Profile).
Add references to assemblies into C# project which are used by F# project.

Categories

Resources