The below example fails with the following error message:
Attempt by method 'Castle.Proxies.PersonProxy.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' to access method 'Castle.DynamicProxy.Generators.Emitters.TypeUtil.Sort(System.Reflection.MemberInfo)' failed.
static void Main(string args)
var person = A.Fake<Person>();
var formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
public class Person
There are tests that asserts that fakes can be serialized so this must have to do with the IL-merge.
Will be released as patch 1.9.1.
Where are the tests for fake serialization? All the tests are running against the merged assembly and they are all passing.
However, you're right that your example doesn't work. If I remove the internalize switch from the merge then it does work, so I guess it's a matter of making some other Castle.Core type public. I'm looking into it...
OK, the plot thickens. Inspection of the TargetSite property of the exception reveals that PersonProxy is "Castle.Proxies.PersonProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null". Note that this assembly is not signed, because the assembly where I wrote the test (FakeItEasy.IntegrationTests) is not signed.
However, when I run the same test from FakeItEasy.Tests, PersonProxy is "Castle.Proxies.PersonProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69" because FakeItEasy.Tests is signed.
This is the reason that CastleDynamicProxyGeneratorTests.Generated_proxies_should_be_serializable() passes. It is written in FakeItEasy.Tests.
The reason the tests pass when DynamicProxyGenAssembly2 is signed and failing when it is not is because we have
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
I'm not yet sure what the solution is.
I now understand this comment http://old.nabble.com/Internalizing-Castle.Core-in-other-Assemblies-td30916966.html#a30921258
for mocking not-strong-named assemblies, I would need a build of
NMock that uses InternalsVisibleTo("DynamicProxyGenAssembly2"),
whereas I would need a build of NMock that uses
InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=...") to mock
a strong-named assembly.
I wouldn't be surprised if Moq, NSubstitute, NMock and RhinoMocks all have the same issue as we are seeing here.
A potential fix for this is to add Castle.DynamicProxy.Generators.Emitters.TypeUtil to the list of types excluded from internalization. I've tested this and it works.
If we're happy with this fix then I'll go ahead and patch 1.9.0 to 1.9.1.
I must say, I'm a little uncomfortable with this 'piecemeal' discovery of 'things in Castle.Core which need to be public'. If we come across another example, I think we should investigate a solution other than merging Castle.Core. Perhaps inclusion of Castle.Core source with namespace transformation. In fact, if that's a route we choose to go down, we should raise a feature request with Castle to produce a source code package with namespace transformations built in.
I might go as far as just cherry pick the pieces of dynamic proxy from Castle.Core that we want. Keep them completely internal to FIE. It should be a very small subset that we need. The potential downside is that it will be harder to get bug-fixes from Castle.Core into our code base.
#74 add failing test
#74 exclude Castle.DynamicProxy.Generators.Emitters.TypeUtil from int…
#74 updated version and release notes
build succeeded http://teamcity.codebetter.com/viewLog.html?buildId=67329&tab=buildResultsDiv&buildTypeId=bt929
Tested this in the big project where I originally found the bug and I can confirm that it works now.