Quantcast
Channel: Entity Framework
Viewing all articles
Browse latest Browse all 10318

Edited Issue: Hide IPOCO interfaces in POCO Proxies [256]

$
0
0
Bug http://entityframework.codeplex.com/workitem/184 talks about enabling JSON serialization by hidding _entityWrapper. We also have a few other strange things in POCO proxies, like the RelationshipManager property. We can easily further simplify how the type looks to POCO serializers by makign the implementation of the interfaces explicit. Here is the code we have to add in the IPOCOImplementor:

// Implement IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
MethodBuilder setChangeTracker = typeBuilder.DefineMethod("IEntityWithChangeTracker.SetChangeTracker", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
typeof(void), new Type[] { typeof(IEntityChangeTracker) });
generator = setChangeTracker.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Stfld, _changeTrackerField);
generator.Emit(OpCodes.Ret);

typeBuilder.DefineMethodOverride(setChangeTracker, typeof(IEntityWithChangeTracker).GetMethod("SetChangeTracker"));

// Implement IEntityWithRelationships.get_RelationshipManager
_getRelationshipManager = typeBuilder.DefineMethod("IEntityWithRelationships.get_RelationshipManager", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.SpecialName | MethodAttributes.Virtual | MethodAttributes.Final,
typeof(RelationshipManager), Type.EmptyTypes);
ILGenerator generator = _getRelationshipManager.GetILGenerator();
Label trueLabel = generator.DefineLabel();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, _relationshipManagerField);
generator.Emit(OpCodes.Brtrue_S, trueLabel);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, s_CreateRelationshipManager);
generator.Emit(OpCodes.Stfld, _relationshipManagerField);
generator.MarkLabel(trueLabel);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, _relationshipManagerField);
generator.Emit(OpCodes.Ret);
relationshipManagerProperty.SetGetMethod(_getRelationshipManager);

typeBuilder.DefineMethodOverride(_getRelationshipManager, typeof(IEntityWithRelationships).GetMethod("get_RelationshipManager"));

Notice the private methods and the call to DefineMethodOverride. This allows to implement interface members explicitly.

Doing this is a minor breacking change in two ways:

1. Serialization format changes: the extra members you used to get weren't very useful, but it is a change anyway.

2. Any code that relies on the interface members being declared directly in the proxy type will break. There are no compelling code patterns that do this, e.g. given a proxy instance, it is easier to cast it to the appropriate interface and invoke a member on that, however it is a change anyway.


Viewing all articles
Browse latest Browse all 10318

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>