0

I'm having problems with a piece of code that behaves differently depending on whether it was compiled in the Release or Debug configuration in Visual Studio. I have manually altered all the project compilation settings I can see on the Release config so that it matches the Debug one, but the problem persists.

The code (below) returns the Guid of the executing assembly:

private static Guid GetApplicationUid() 
{ 
   Assembly assembly = Assembly.GetCallingAssembly(); 
   GuidAttribute attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), false)[0]; 
   return new Guid(attribute.Value); 
}

The method fails with an "Index was outside the bounds of the array." exception when executed after compilation in Release mode. It works correctly in Debug mode. The reason this is that in this configuration, the assembly reference created by GetExecutingAssembly() is to a temporary assembly (eg. App_Web_eelfd0ff, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null) rather than the underlying "real" one.

Strangely enough, I have another component running in the same web that uses the same code and behaves the same regardless of the compilation mode.

Why is this happening and how to prevent it?

Paul Taylor
  • 5,651
  • 5
  • 44
  • 68
  • 1
    Does it change based on which configuration you're building, or does it change based on whether you're in the debugger or not? – Damien_The_Unbeliever Jan 12 '13 at 17:36
  • possible duplicate of [Why is this assembly a temporary asp.net dll?](http://stackoverflow.com/questions/4333833/why-is-this-assembly-a-temporary-asp-net-dll) – Hans Passant Jan 12 '13 at 17:42
  • That article suggests that the compilation model is different between debug and release modes, but it doesn't explain how to prevent the temporary dll being returned in release mode. – Paul Taylor Jan 12 '13 at 18:36
  • @Damien_The_Unbeliever it changes according to the config. – Paul Taylor Jan 12 '13 at 23:11
  • 1
    Your method may be being inlined. Try adding `MethodImplOptions.NoInlining`, as per [this answer](http://stackoverflow.com/a/5169272/15498) – Damien_The_Unbeliever Jan 13 '13 at 06:33
  • @Damien_The_Unbeliever yes! Had to work my way up the call stack to find the method that was being inlined (above code is simplified), but that has done the trick. Put that up as an answer and I'll mark it as such, many thanks. – Paul Taylor Jan 13 '13 at 09:06

2 Answers2

1

It's possible that when optimizations are enabled, the function is being inlined into a different assembly. Try adding MethodImplOptions.NoInlining, as per this answer so that the method is in the assembly you think it is.

Community
  • 1
  • 1
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
0

The exception means the assembly does not have a GUID attribute. At a guess, it may be optimized away by the compiler in release mode if the assembly is not set to be COM visible1. Check your other working assembly to see if it is registered for COM interop.

1GUID's are only used in .NET assemblies for COM interop. Visual Studio by automatically adds a GUID for you when you create a new project in case you want to do COM interop, but otherwise it is useless.

just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
  • Neither assembly is registered for COM interop. You are right in saying that the assembly inspected by the code has no Guid attribute, but the reason for that is that in release mode, it is getting the temporary dll, not the real one. – Paul Taylor Jan 12 '13 at 19:13