/// <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();
     }
 }