/// <summary> /// Sets a delegate onto the _compareByteArrays field such that it can be executed to check /// whether two byte arrays are the same by value comparison. /// </summary> private static void SetCompareByteArraysDelegate(Type proxyType, EntityProxyTypeInfo proxyTypeInfo) { var compareByteArraysField = proxyType.GetField(CompareByteArraysFieldName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic); Debug.Assert(compareByteArraysField != null, "Expected compareByteArraysField to be defined on the proxy type."); AssignInterceptionDelegate(new Func<object, object, bool>(ByValueEqualityComparer.Default.Equals), compareByteArraysField); }
/// <summary> /// Sets a delegate onto the _resetFKSetterFlag field such that it can be executed to make /// a call into the state manager to reset the InFKSetter flag. /// </summary> private static void SetResetFKSetterFlagDelegate(Type proxyType, EntityProxyTypeInfo proxyTypeInfo) { var resetFKSetterFlagField = proxyType.GetField(ResetFKSetterFlagFieldName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic); Debug.Assert(resetFKSetterFlagField != null, "Expected resetFKSetterFlagField to be defined on the proxy type."); var resetFKSetterFlagDelegate = GetResetFKSetterFlagDelegate(proxyTypeInfo.EntityWrapperDelegate); AssignInterceptionDelegate(resetFKSetterFlagDelegate, resetFKSetterFlagField); }
private static void InterceptMember(EdmMember member, Type proxyType, EntityProxyTypeInfo proxyTypeInfo) { PropertyInfo property = EntityUtil.GetTopProperty(proxyType, member.Name); Debug.Assert(property != null, String.Format(CultureInfo.CurrentCulture, "Expected property {0} to be defined on proxy type {1}", member.Name, proxyType.FullName)); FieldInfo interceptorField = proxyType.GetField(LazyLoadImplementor.GetInterceptorFieldName(member.Name), BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic); Debug.Assert(interceptorField != null, String.Format(CultureInfo.CurrentCulture, "Expected interceptor field for property {0} to be defined on proxy type {1}", member.Name, proxyType.FullName)); Delegate interceptorDelegate = typeof(LazyLoadBehavior).GetMethod("GetInterceptorDelegate", BindingFlags.NonPublic | BindingFlags.Static). MakeGenericMethod(proxyType, property.PropertyType). Invoke(null, new object[] { member, proxyTypeInfo.EntityWrapperDelegate }) as Delegate; AssignInterceptionDelegate(interceptorDelegate, interceptorField); }
/// <summary> /// Build a CLR proxy type for the supplied EntityType. /// </summary> /// <param name="ospaceEntityType"> /// EntityType in O-Space that represents the CLR type to be proxied. /// </param> /// <returns> /// EntityProxyTypeInfo object that contains the constructed proxy type, /// along with any behaviors associated with that type; /// or null if a proxy type cannot be constructed for the specified EntityType. /// </returns> private static EntityProxyTypeInfo BuildType(ModuleBuilder moduleBuilder, ClrEntityType ospaceEntityType) { Debug.Assert(s_TypeMapLock.IsUpgradeableReadLockHeld, "EntityProxyTypeInfo.BuildType method was called without first acquiring an upgradeable read lock from s_TypeMapLock."); EntityProxyTypeInfo proxyTypeInfo; ProxyTypeBuilder proxyTypeBuilder = new ProxyTypeBuilder(ospaceEntityType); Type proxyType = proxyTypeBuilder.CreateType(moduleBuilder); if (proxyType != null) { // Set the runtime assembly of the proxy types if it hasn't already been set. // This is used by the IsProxyType method. Assembly typeAssembly = proxyType.Assembly; if (!ProxyRuntimeAssemblies.Contains(typeAssembly)) { ProxyRuntimeAssemblies.Add(typeAssembly); AddAssemblyToResolveList(typeAssembly); } proxyTypeInfo = new EntityProxyTypeInfo(proxyType, ospaceEntityType, proxyTypeBuilder.CreateInitalizeCollectionMethod(proxyType), proxyTypeBuilder.BaseGetters, proxyTypeBuilder.BaseSetters); foreach (EdmMember member in proxyTypeBuilder.LazyLoadMembers) { InterceptMember(member, proxyType, proxyTypeInfo); } SetResetFKSetterFlagDelegate(proxyType, proxyTypeInfo); SetCompareByteArraysDelegate(proxyType, proxyTypeInfo); } else { proxyTypeInfo = null; } return proxyTypeInfo; }
internal static bool TryGetProxyType(Type proxyType, out EntityProxyTypeInfo proxyTypeInfo) { s_TypeMapLock.EnterReadLock(); try { return s_ProxyTypeMap.TryGetValue(proxyType, out proxyTypeInfo); } finally { s_TypeMapLock.ExitReadLock(); } }
internal static bool TryGetProxyType(Type clrType, string entityTypeName, out EntityProxyTypeInfo proxyTypeInfo) { s_TypeMapLock.EnterReadLock(); try { return s_ProxyNameMap.TryGetValue(new Tuple<Type, string>(clrType, entityTypeName), out proxyTypeInfo); } finally { s_TypeMapLock.ExitReadLock(); } }