Friday, November 28, 2008

The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias

Extension methods are cool and they can be used from .NET 2.0. I'm not the first to suss this out but the trick is to add the following to your code.

namespace System.Runtime.CompilerServices
{
  internal sealed class ExtensionAttribute : Attribute { }
}

This works well but there is a gotcha. Say I have two assemblies and I've added the definition to both assemblies because I want to add extension methods to both, I get the warning message

The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias

I try to produce code that doesn't generate any warnings since it's easy to miss real warnings if there are these kind of false positives. One solution is to make the definition public in one of the assemblies but I wasn't keen on that idea because the assembly is a publicly available class library whose public API I didn't want to pollute with this hack.

So the final solution was to use the InternalVisibleTo attribute in one of the assemblies. This means ExtensionAttribute only needs to be defined in one assembly. There's more info here on how to do that with strongly named assemblies since it's not completely straight forward.

One final problem is that using the assembly in a .NET 3.5 application will show the warning again since ExtensionAttribute is already defined in the .NET Framework. As far as I'm aware there isn't a solution for this problem, except producing separate .NET 2 and .NET 3.5 versions of the assembly.

5 comments:

Anonymous said...

Greeting, I just ran into this (and your site via google) and my way around it was to mark the ExtensionAttribute internal, the compiler hasn't complained and since all my extension methods are contained in the one assembly, don't think it will be a problem. Of course I'd rather just move to 3.5, but some wheels turn slowly.

Anonymous said...

Opps, just realised this isn't going to fix my problem!

Doogal said...

I think that approach works fine if your extension methods are just in the one assembly, it just gets tricky when you want to add them to two separate assemblies

Richard Dingwall said...

Duplicate types also affects ILMerge:

An exception occurred during merging:
ILMerge.Merge: ERROR!!: Duplicate type 'System.Runtime.CompilerServices.ExtensionAttribute' found in assembly '...'.
at ILMerging.ILMerge.MergeInAssembly(AssemblyNode a, Boolean makeNonPublic)
at ILMerging.ILMerge.Merge()
at ILMerging.ILMerge.Main(String[] args)

But you can work around it with the /allowDup switch:

ILMerge.exe /allowDup:ExtensionAttribute ...

Unknown said...

In my case that fuc... error was in my websites build for .net 4.0 that has this fuc... line:

[assembly: System.Security.AllowPartiallyTrustedCallers]

Remove it from your webforms and check the impact if you show reports because with .net 4.0 is there another way to configure this!!!