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

Castle.DynamicProxy.ProxyGenerationException when creating mock. #585

Closed
compact-github opened this issue Aug 22, 2019 · 8 comments
Closed

Comments

@compact-github
Copy link

compact-github commented Aug 22, 2019

When creating mock using Substitute.For method got exception : Castle.DynamicProxy.ProxyGenerationException: Duplicate element: Castle.DynamicProxy.Generators.MetaMethod.

To Reproduce
Create two identical interfaces with one identical method in two namespaces.
Inherit one of the interfaces and define the same method.
sample setup:

namespace firstNamespace
{
    public interface BaseObject1
    {
        string SomeMethod { get; }
    }
}
namespace SecondNamespace
{
    public interface BaseObject1
    {
        string SomeMethod { get; }
    }
    public interface BaseFolder1 : BaseObject1
    {
        string SomeMethod { get; }
    }
}

Try create mock using Substitute.For method like that:
firstNamespace.BaseObject1 mock = Substitute.For<firstNamespace.BaseObject1, SecondNamespace.BaseFolder1>();

At first attempt please use exactly the same name for namespaces and interfaces. Even small change eg. FirstNamespace instead of firstNamespace magically fixes this issue.

Expected behaviour
Allow creating mock for provided scenario.

Environment:

  • NSubstitute version: 4.2.1.0
  • NSubstitute.Analyzers version: unable to successfully install
  • Platform: windows 8.1, Visual Studio Express Edition 2015 version 14.0.25123.00 update 2, Net Framework version 4.8.03761

Additional context
Sample VS project reproducing the issue is attached here:
NSubstituteIssue.zip

Stack trace from exception:

  at Castle.DynamicProxy.Generators.TypeElementCollection`1.Add(TElement item)
   at Castle.DynamicProxy.Contributors.CompositeTypeContributor.CollectElementsToProxy(IProxyGenerationHook hook, MetaType model)
   at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
   at Castle.DynamicProxy.Generators.ClassProxyGenerator.<>c__DisplayClass1_0.<GenerateCode>b__0(String n, INamingScope s)
   at Castle.DynamicProxy.Generators.BaseProxyGenerator.<>c__DisplayClass34_0.<ObtainProxyType>b__0(CacheKey _)
   at Castle.Core.Internal.SynchronizedDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
   at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
   at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
   at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
   at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.CreateProxyUsingCastleProxyGenerator(Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments, IInterceptor[] interceptors, ProxyGenerationOptions proxyGenerationOptions)
   at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateTypeProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
   at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
   at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments, Boolean callBaseByDefault)
   at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments)
   at NSubstitute.Substitute.For(Type[] typesToProxy, Object[] constructorArguments)
   at NSubstitute.Substitute.For[T1,T2](Object[] constructorArguments)
   at NSubstituteIssue.UnitTest1.TestMethod1() in C:\NSubstituteIssue\NSubstituteIssue\UnitTest1.cs:line 35
@zvirja
Copy link
Contributor

zvirja commented Aug 22, 2019

Thanks for the brilliantly crafted scenario!

@stakx Hey! If you have time these days, could you please take a look? It looks like a pure Castle issue, as we pass interfaces just as is (like Moq I believe).

If you don’t have time - it’s totally OK, we could also investigate it ourselves.

Thanks!

@stakx
Copy link

stakx commented Aug 22, 2019

@zvirja, thanks for the ping, I'll take a look and report what I find.

@stakx
Copy link

stakx commented Aug 23, 2019

We've fixed the root cause for this problem in DynamicProxy. Thank you all for bringing this to our attention!

@tpodolak
Copy link
Member

NSubstitute.Analyzers version: unable to successfully install

@compact-github could you tell what was wrong when you tried to install NSubstitute.Analyzers?

@compact-github
Copy link
Author

Sure. Using Nuget Package manager I installed NSubstitute.Analyzers.CSharp package in version 1.0.10.
After that, when compiling project I got:

CSC : warning CS8032: An instance of analyzer NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers.NonSubstitutableMemberWhenAnalyzer cannot be created from C:\NSubstituteIssue\packages\NSubstitute.Analyzers.CSharp.1.0.10\analyzers\dotnet\cs\NSubstitute.Analyzers.CSharp.dll : Could not load file or assembly 'Microsoft.CodeAnalysis, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified..

So I installed Microsoft.CodeAnalysis package in version 1.3.1. This installed also 18 additional packages.
I got exactly the same warn as previous, preceded by:

C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): warning MSB3274: The primary reference "Microsoft.CodeAnalysis.Workspaces.Desktop, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" could not be resolved because it was built against the ".NETFramework,Version=v4.5.2" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v4.5".

I tried update Microsoft.CodeAnalysis to most recent version 3.2.1. Nothing changed, so I updated rest of the packages installed with Microsoft.CodeAnalyzers.
Still no success and I gave up. I'm not familiar with the analyzer stuff. Maybe problem is related to my old Visual Studio Express edition.

Sorry for the delayed answer, but during weekend I was out of internet.

@tpodolak
Copy link
Member

@compact-github you most likely use Visual Studio version which is not compatible with the analyzers. Can you check if your Visual Studio falls into supported version range listed in docs?

@compact-github
Copy link
Author

@tpodolak Yes, you are right. Visual Studio 2015 Express is not supported. Even Visual Studio 2015 is not supported. For me is not a problem. For noncommercial activity I can download more recent community version. In the company we have few full version Visual Studio licenses. I'm not full time c# developer so currently I don't have any and use old express version.

@304NotModified
Copy link
Contributor

304NotModified commented Apr 30, 2024

Closing this due to inactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants