Skip to content

DispatchProxy can fail to generate new proxy types - namespace collision? #43685

Description

@DaleStan

Description

Consider three assemblies, as follows:

One.dll

using System.Reflection;

public static class TestOne
{
    public static void DoThing()
    {
        DispatchProxy.Create<ITestOne, Proxy>();
    }
}

internal interface ITestOne { }

public class Proxy : DispatchProxy
{
    protected override object Invoke(MethodInfo targetMethod, object[] args) => throw null;
}

Two.dll

Identical to One.dll, except that it declares class TestTwo and interface ITestTwo.

Three.exe

TestOne.DoThing(); // Works
TestTwo.DoThing(); // Throws a TypeLoadException from DispatchProxy.Create

The expected behavior is that either both calls to DispatchProxy.Create will succeed, or both calls will fail. The observed behavior is that the second call will fail regardless of the order the calls. That is, if the order of the calls is reversed, TestTwo.DoThing() will succeed and TestOne.DoThing() will fail.

The two libraries work perfectly well on their own, but they cannot be used together.

Configuration

I've tested this in Core 2.0, Core 3.1, Framework 4.6.2, and 5.0 Most tests were done with System.Reflection.DispatchProxy 4.7.1, but I also did a few tests with System.Reflection.DispatchProxy 4.0.0.

All tests were run on Windows 10 64-bit.

Other information

In .NET Framework 4.6.2 and .NET Core 2.0, the TypeLoadException is:

System.TypeLoadException: Type 'generatedProxy_2' from assembly 'ProxyBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is attempting to implement an inaccessible interface.
   at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
   at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
   at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
   at System.Reflection.DispatchProxyGenerator.ProxyBuilder.CreateType()
   at System.Reflection.DispatchProxyGenerator.GenerateProxyType(Type baseType, Type interfaceType)
   at System.Reflection.DispatchProxyGenerator.GetProxyType(Type baseType, Type interfaceType)
   at System.Reflection.DispatchProxyGenerator.CreateProxyInstance(Type baseType, Type interfaceType)
   at System.Reflection.DispatchProxy.Create[T,TProxy]()
   at Two.Test.DoThing()
   at $Program.$Main(String[] args)

In .NET Core 3.1, and .NET 5.0 the TypeLoadException does not have the TermCreateClass stack frame, but otherwise appears to be identical.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions