.NET 4.0 and NotSupportedException complaining about dynamic assemblies

If you search for “The invoked member is not supported in a dynamic assembly” error message, you will get plenty of results. Some of them related to code that worked in .NET 2.0 and 3.x but suddenly stopped working in .NET 4.0. What may be surprising is that this error comes from the places that have nothing to do with dynamic assemblies. In fact, they are not created in application code.

Here’s an example of the code that can break:

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    var assemblies = from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
                              where !(assembly is System.Reflection.Emit.AssemblyBuilder) &&
                              !assembly.GlobalAssemblyCache &&
                              assembly.CodeBase != Assembly.GetExecutingAssembly().CodeBase
                              select assembly;

    foreach (var assembly in assemblies)
    {
        // rest of the code is skipped
    }
}

What’s wrong with this code when it comes to dynamic assemblies? Nothing as long as it’s running in CLR prior to .NET 4.0. Apparently the check assembly is System.Reflection.Emit.AssemblyBuilder is no longer enough if you want to detect dynamic assembly under CLR 4.0. There may be dynamic assemblies that pass this test and System.NotSupportedException will be thrown on attempt to call CodeBase property on them, since they CodeBase doesn’t make sense for a dynamic assembly.

However, one additional check helps: a check for assembly full name mathcing System.Reflection.Emit.InternalAssemblyBuilder. So the code above should be rewritten in the following way:

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    var assemblies = from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
                              where !(assembly is System.Reflection.Emit.AssemblyBuilder) &&
                              assembly.GetType().FullName != "System.Reflection.Emit.InternalAssemblyBuilder" &&
                              !assembly.GlobalAssemblyCache &&
                              assembly.CodeBase != Assembly.GetExecutingAssembly().CodeBase
                              select assembly;

    foreach (var assembly in assemblies)
    {
        // rest of the code is skipped
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s