Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeLoadException: Internal method from another assembly does not have an implementation #1142

Closed
heldergoncalves92 opened this issue Feb 5, 2021 · 4 comments
Labels

Comments

@heldergoncalves92
Copy link

heldergoncalves92 commented Feb 5, 2021

Work State

Moq version: 4.10.0.0 (C#)
TargetFramework: net5.0

I have the following interfaces in the assembly ProjectA:

public interface IView {
    void Method_1();
    internal void InternalMethod();    
}

public interface IViewModule {
     IView Host();
}

Then in another project, ProjectB, that consumes ProjectA, I just have visibility to Method_1. That's fine and everything seems to work. Except for tests that are failing.

In ProjectB I have another interface that inherits from IView.

public interface IExtendedView : IView {
    // Other methods   
}

Test that fails

Now I will show you the code that will create the exception:

void MockViewModule() {
    var viewModule = new Mock<IViewModule>();
    var view = new Mock<IExtendedView>();
    
    // It crashes in the next line
    viewModule.SetupGet(x => x.Host).Returns(view.Object);
}

Error Message

Message: 
    System.TypeLoadException : Method 'InternalMethod' in type 'Castle.Proxies.IExtendedViewProxy_5' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

Stack Trace: 
    TypeBuilder.CreateTypeNoLock()
    TypeBuilder.CreateTypeInfo()
    AbstractTypeEmitter.CreateType(TypeBuilder type)
    AbstractTypeEmitter.BuildType()
    InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
    <>c__DisplayClass6_0.<GenerateCode>b__0(String n, INamingScope s)
    BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
    InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
    DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
    ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
    ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
    CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
    Mock`1.InitializeInstancePexProtected()
    PexProtector.Invoke(Action action)
    Mock`1.InitializeInstance()
    Mock`1.OnGetObject()
    Mock.get_Object()
    Mock`1.get_Object()

I would like to understand if there's a way to avoid this exception.

@stakx
Copy link
Contributor

stakx commented Feb 5, 2021

Initial suspicion: possibly related to / caused by the same underlying problem as #991.

@heldergoncalves92
Copy link
Author

Are you sure @stakx? I just added the stack trace, and it seems to be quite different from #991.

@stakx
Copy link
Contributor

stakx commented Feb 5, 2021

No, I'm not yet sure. (That's why I wrote "initial suspicion", it was more of a semi-informed guess aka gut feeling.) You can ignore my above post, it was mostly a reminder for myself for when I get time to look at this in detail. 🙂

@stakx
Copy link
Contributor

stakx commented Feb 26, 2021

@heldergoncalves92 – in case you haven't solved this yet yourself, you'll need to add the following somewhere in your ProjectA (the project that defines IView):

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Alternatively, add a default implementation for InternalMethod directly in the interface, instead of only declaring it.

Reason: It isn't possible for DynamicProxy (the proxying library on top of which Moq 4 is built) to create a full implementation class of IView if InternalMethod isn't accessible to it. Once you make IView's internals accessible to DynamicProxy, it can then implement the method in a dynamically generated subtype (proxy class).

The InternalsVisibleTo attribute is explained a bit in the Quickstart.

@stakx stakx closed this as completed Feb 26, 2021
@stakx stakx added the question label Feb 26, 2021
@devlooped devlooped locked and limited conversation to collaborators Sep 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants