OK, thank you very much for your help. Creating my own "fork" and removing the limitation is probably the second best solution, way better than the hack I have now. It was never actually meant to stay in, I was going to mail the group about it sooner or later and suggest the change to DynamicProxy but I never got around to it. And it just kept working! The best solution to ME is obviously to remove the limitation in the next version but as I said before I do realize that it's a breaking change and that people might object to it.
I think it's funny that this issue came up though, lesson learned: hacks will always come back and bite you. Always. ;-) I added a feature request to user voice, hope it gets voted for! Cheers, Patrik 2010/4/19 Krzysztof Koźmic <[email protected]> > OK, I see now. > > I don't remember exactly how the old version worked, but v2.2 is very > explicit about which method is interface implementation so it's not that > easy to fool it like that :) > Since DP is OSS you can always go ahead and remove the limitation: (it's in > AcceptMethod of MembersCollector). > Go ahead and suggest making this change in http://castle.uservoice.comwe'll > see if people think it's a good idea. If it is and no one objects, > I'll make this option available in DP vNext. > > cheers, > Krzysztof > > > > On 2010-04-19 21:00, Patrik Hägne wrote: > > I don't "use" the interface, I only have the proxy implement the interface, > this way it is "fooled" to not think that a call to the ToString method is > to the Object.ToString-method but to the ToString-method of the interface > and therefore it's intercepted (at least in versions previous to 2.2). There > are tests in > http://code.google.com/p/fakeiteasy/source/browse/Source/FakeItEasy.Tests/DynamicProxy/DynamicProxyProxyGeneratorTests.cs > that > asserts that the object methods can be intercepted, for example "public > void GeneratedProxies_should_intercept_calls_to_ToString()". When running > this test compiled against version 2.1 it works, but when running compiled > against 2.2 it fails. > > My solution for now is to make the interface public (which is exposing > the hack even more) and continue to use version 2.1. I for one would very > much like the relaxations you mention but maybe other people would have > other issues with that that I can not foresee. It would be very nice to get > rid of the hack and still be able to intercept these members since it brings > great value. To configure the "ToString" method is something very useful in > tests. > > 2010/4/19 Krzysztof Koźmic <[email protected]> > >> Well you have to cast the proxy to the interface to have its members >> intercepted. How did you use the interface? I couldn't find any tests in >> your repository. >> I'm more or less OK with relaxing the requirement for interception of >> Object members. For default scenario the default hook would filter these >> out, and if you had custom hook, you could choose to intercept object >> members. >> That would be a breaking change though. I don't know what other ppl think >> about it? >> >> Krzysztof >> >> >> >> On 2010-04-19 19:37, Patrik Hägne wrote: >> >> The problem seems to boil down to the fact that ICanInterceptObjectMembers >> is internal. If I make it public I can remove the >> InternalsVisibleTo-attribute and it works. The second problem still remains >> though. It seems to me that my "hack" is not the best way here, and in the >> general case I understand the rational behind not letting the object-members >> being interceptable but in the fake-case it's pretty handy, I've provided a >> way to have sencible default values for these members so it doesn't end up >> with every fake object having the GetHashCode returning 0 as default. Is >> there any other way to allow me to intercept these members? The way I solved >> it earlier was having all my fake proxies implement the >> ICanInterceptObjectMembers like this: >> >> private static Type[] interfacesToImplement = new Type[] { >> typeof(IFakedProxy), typeof(ICanInterceptObjectMembers) }; >> >> ... >> >> (IFakedProxy)proxyGenerator.CreateInterfaceProxyWithoutTarget(typeToProxy, >> GetAllInterfacesToImplement(additionalInterfacesToImplement), >> fakeObjectInterceptor, proxyResult); >> >> As you see, all proxies implements the two interfaces in the >> "interfacesToImplement" member, it can also implement other interfaces >> beyond this that are added by the GetAllInterfacesToImplementMethod. >> >> See the full code here: >> http://code.google.com/p/fakeiteasy/source/browse/Source/FakeItEasy/DynamicProxy/DynamicProxyProxyGenerator.cs >> >> Cheers, >> Patrik >> >> 2010/4/19 Krzysztof Koźmic <[email protected]> >> >>> 1. If you specify InternalsVisibleTo w/o the key, would it work? >>> 2. How do you use the ICanInterceptObjectMembers? >>> >>> Krzysztof >>> >>> >>> >>> >>> On 2010-04-19 19:14, Patrik Hägne wrote: >>> >>> I did update, or at least I thought I did, here is a message I get now >>> and I think it's the same and I'm positive that the assemblies has now been >>> built against version 2.2.0.6628. >>> >>> System.TypeLoadException : Type >>> 'Castle.Proxies.ITypeWithFakeablePropertiesProxy' from assembly >>> 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, >>> PublicKeyToken=null' is attempting to implement an inaccessible interface. >>> at System.Reflection.Emit.TypeBuilder._TermCreateClass(Int32 handle, >>> Module module) >>> at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() >>> at System.Reflection.Emit.TypeBuilder.CreateType() >>> at >>> Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder >>> type) >>> at >>> Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() >>> at >>> Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType(String >>> typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope) >>> at >>> Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type >>> proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) >>> at >>> Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type >>> interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions >>> options) >>> at >>> Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type >>> interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions >>> options) >>> at >>> Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type >>> interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions >>> options, IInterceptor[] interceptors) >>> at >>> Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type >>> interfaceToProxy, Type[] additionalInterfacesToProxy, IInterceptor[] >>> interceptors) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\DynamicProxy\DynamicProxyProxyGenerator.cs(85,0): at >>> FakeItEasy.DynamicProxy.DynamicProxyProxyGenerator.CreateInterfaceProxy(Type >>> typeToProxy, IEnumerable`1 additionalInterfacesToImplement, >>> FakeObjectInterceptor fakeObjectInterceptor) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\DynamicProxy\DynamicProxyProxyGenerator.cs(145,0): at >>> FakeItEasy.DynamicProxy.DynamicProxyProxyGenerator.DoGenerateProxy(Type >>> typeToProxy, IEnumerable`1 additionalInterfacesToImplement, FakeObject >>> fakeObject, IEnumerable`1 argumentsForConstructor) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\DynamicProxy\DynamicProxyProxyGenerator.cs(50,0): at >>> FakeItEasy.DynamicProxy.DynamicProxyProxyGenerator.GenerateProxy(Type >>> typeToProxy, IEnumerable`1 additionalInterfacesToImplement, FakeObject >>> fakeObject, IEnumerable`1 argumentsForConstructor) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\Core\Creation\DefaultFakeAndDummyManager.cs(119,0): >>> at FakeItEasy.Core.Creation.DefaultFakeAndDummyManager.CreateProxy(Type >>> typeOfProxy, IEnumerable`1 additionalInterfacesToImplement, IEnumerable`1 >>> argumentsForConstructor, Boolean throwOnFailure) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\Core\Creation\DefaultFakeAndDummyManager.cs(63,0): at >>> FakeItEasy.Core.Creation.DefaultFakeAndDummyManager.CreateFake(Type >>> typeOfFake, FakeOptions options) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\Core\Creation\DefaultFakeCreator.cs(39,0): at >>> FakeItEasy.Core.Creation.DefaultFakeCreator.CreateFake[T](Action`1 options) >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy\A.cs(40,0): at FakeItEasy.A.Fake[T]() >>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>> Name\Source\FakeItEasy.IntegrationTests\GeneralTests.cs(22,0): at >>> FakeItEasy.IntegrationTests.GeneralTests.Faked_object_with_fakeable_properties_should_have_fake_as_default_value() >>> >>> This update leads to another unfortunate side-effect though, which is >>> pretty much my fault to begin with, 'cause I've made a bit of a hack. The >>> thing is that DynamicProxy doesn't intercept the object-members (ToString, >>> GetHashCode and Equals) which is a big issue for me becuase I really want to >>> be able to intercept those methods in order to configure them on >>> mocks/stubs. The way I've gotten around this is to have all proxies I >>> generate implement a special interface: >>> >>> internal interface ICanInterceptObjectMembers >>> { >>> string ToString(); >>> >>> bool Equals(object o); >>> >>> int GetHashCode(); >>> } >>> >>> When updating to the latest version these methods are no longer >>> intercepted. Is there any way around this? >>> >>> /Patrik >>> >>> 2010/4/19 Krzysztof Koźmic <[email protected]> >>> >>>> Check with Dynamic Proxy v2.2 if the issue occurs. >>>> >>>> Krzysztof >>>> >>>> >>>> >>>> On 2010-04-19 18:57, Patrik Hägne wrote: >>>> >>>>> I'm in the process of putting out a signed version of FakeItEasy >>>>> (http://code.google.com/p/fakeiteasy/) that is using DynamicProxy2. >>>>> When doing this some of my integration tests fails with an exception >>>>> message similar to the one below. Also when deploying the new, signed >>>>> verision in a large application with thousands of tests that uses >>>>> FakeItEasy something like 30% of the tests fails with a similar >>>>> exception. I have the InternalsVisibleTo-attribute for DynamicProxy2 >>>>> set on all FakeItEasy-assemblies like this: >>>>> >>>>> [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, >>>>> >>>>> PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] >>>>> >>>>> The exception: >>>>> >>>>> System.TypeLoadException : Type >>>>> 'ITypeWithFakeablePropertiesProxy3d17a4446fea440f9c91aec9693fd7d7' >>>>> from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, >>>>> Culture=neutral, PublicKeyToken=null' is attempting to implement an >>>>> inaccessible interface. >>>>> at System.Reflection.Emit.TypeBuilder._TermCreateClass(Int32 >>>>> handle, >>>>> Module module) >>>>> at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() >>>>> at System.Reflection.Emit.TypeBuilder.CreateType() >>>>> at >>>>> Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() >>>>> at >>>>> >>>>> Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type >>>>> proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) >>>>> at >>>>> >>>>> Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type >>>>> interfaceToProxy, Type[] additionalInterfacesToProxy, >>>>> ProxyGenerationOptions options, IInterceptor[] interceptors) >>>>> at >>>>> >>>>> Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type >>>>> interfaceToProxy, Type[] additionalInterfacesToProxy, IInterceptor[] >>>>> interceptors) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\DynamicProxy\DynamicProxyProxyGenerator.cs(85,0): >>>>> at >>>>> >>>>> FakeItEasy.DynamicProxy.DynamicProxyProxyGenerator.CreateInterfaceProxy(Type >>>>> typeToProxy, IEnumerable`1 additionalInterfacesToImplement, >>>>> FakeObjectInterceptor fakeObjectInterceptor) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\DynamicProxy\DynamicProxyProxyGenerator.cs(145,0): >>>>> at >>>>> FakeItEasy.DynamicProxy.DynamicProxyProxyGenerator.DoGenerateProxy(Type >>>>> typeToProxy, IEnumerable`1 additionalInterfacesToImplement, FakeObject >>>>> fakeObject, IEnumerable`1 argumentsForConstructor) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\DynamicProxy\DynamicProxyProxyGenerator.cs(50,0): >>>>> at >>>>> FakeItEasy.DynamicProxy.DynamicProxyProxyGenerator.GenerateProxy(Type >>>>> typeToProxy, IEnumerable`1 additionalInterfacesToImplement, FakeObject >>>>> fakeObject, IEnumerable`1 argumentsForConstructor) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\Core\Creation\DefaultFakeAndDummyManager.cs(119,0): >>>>> at >>>>> FakeItEasy.Core.Creation.DefaultFakeAndDummyManager.CreateProxy(Type >>>>> typeOfProxy, IEnumerable`1 additionalInterfacesToImplement, >>>>> IEnumerable`1 argumentsForConstructor, Boolean throwOnFailure) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\Core\Creation\DefaultFakeAndDummyManager.cs(63,0): >>>>> at FakeItEasy.Core.Creation.DefaultFakeAndDummyManager.CreateFake(Type >>>>> typeOfFake, FakeOptions options) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\Core\Creation\DefaultFakeCreator.cs(39,0): at >>>>> FakeItEasy.Core.Creation.DefaultFakeCreator.CreateFake[T](Action`1 >>>>> options) >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy\A.cs(40,0): at FakeItEasy.A.Fake[T]() >>>>> C:\Users\Patrik\Documents\Code\FakeItEasy\FakeItEasy - Strong >>>>> Name >>>>> \Source\FakeItEasy.IntegrationTests\GeneralTests.cs(22,0): at >>>>> >>>>> FakeItEasy.IntegrationTests.GeneralTests.Faked_object_with_fakeable_properties_should_have_fake_as_default_value() >>>>> >>>>> I spoke to Krzysztof via e-mail and he suggested that I should update >>>>> to the latest version (2.2) and I've just tried that but I get the >>>>> same error. >>>>> >>>>> Any ideas? I could provide you with the full source if you'd like for >>>>> debugging. >>>>> >>>>> Cheers, >>>>> Patrik >>>>> >>>>> >>>>> >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Castle Project Users" group. >>>> To post to this group, send email to >>>> [email protected]. >>>> To unsubscribe from this group, send email to >>>> [email protected]<castle-project-users%[email protected]> >>>> . >>>> For more options, visit this group at >>>> http://groups.google.com/group/castle-project-users?hl=en. >>>> >>>> >>> >>> >>> -- >>> Patrik Hägne >>> Rosenbergsgatan 18B >>> 254 44 HELSINGBORG >>> SWEDEN >>> Tfn: +46 (0) 701 64 85 52 >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Castle Project Users" group. >>> To post to this group, send email to >>> [email protected]. >>> To unsubscribe from this group, send email to >>> [email protected]. >>> For more options, visit this group at >>> http://groups.google.com/group/castle-project-users?hl=en. >>> >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Castle Project Users" group. >>> To post to this group, send email to >>> [email protected]. >>> To unsubscribe from this group, send email to >>> [email protected]<castle-project-users%[email protected]> >>> . >>> For more options, visit this group at >>> http://groups.google.com/group/castle-project-users?hl=en. >>> >> >> >> >> -- >> Patrik Hägne >> Rosenbergsgatan 18B >> 254 44 HELSINGBORG >> SWEDEN >> Tfn: +46 (0) 701 64 85 52 >> -- >> You received this message because you are subscribed to the Google Groups >> "Castle Project Users" group. >> To post to this group, send email to >> [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/castle-project-users?hl=en. >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Castle Project Users" group. >> To post to this group, send email to >> [email protected]. >> To unsubscribe from this group, send email to >> [email protected]<castle-project-users%[email protected]> >> . >> For more options, visit this group at >> http://groups.google.com/group/castle-project-users?hl=en. >> > > > > -- > Patrik Hägne > Rosenbergsgatan 18B > 254 44 HELSINGBORG > SWEDEN > Tfn: +46 (0) 701 64 85 52 > -- > You received this message because you are subscribed to the Google Groups > "Castle Project Users" group. > To post to this group, send email to [email protected] > . > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/castle-project-users?hl=en. > > > -- > You received this message because you are subscribed to the Google Groups > "Castle Project Users" group. > To post to this group, send email to [email protected] > . > To unsubscribe from this group, send email to > [email protected]<castle-project-users%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/castle-project-users?hl=en. > -- Patrik Hägne Rosenbergsgatan 18B 254 44 HELSINGBORG SWEDEN Tfn: +46 (0) 701 64 85 52 -- You received this message because you are subscribed to the Google Groups "Castle Project Users" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.
