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.

Reply via email to