private static EntityProxyTypeInfo BuildType( ModuleBuilder moduleBuilder, ClrEntityType ospaceEntityType, MetadataWorkspace workspace) { EntityProxyFactory.ProxyTypeBuilder proxyTypeBuilder = new EntityProxyFactory.ProxyTypeBuilder(ospaceEntityType); Type type = proxyTypeBuilder.CreateType(moduleBuilder); EntityProxyTypeInfo proxyTypeInfo; if (type != (Type)null) { Assembly assembly = type.Assembly(); if (!EntityProxyFactory._proxyRuntimeAssemblies.Contains(assembly)) { EntityProxyFactory._proxyRuntimeAssemblies.Add(assembly); EntityProxyFactory.AddAssemblyToResolveList(assembly); } proxyTypeInfo = new EntityProxyTypeInfo(type, ospaceEntityType, proxyTypeBuilder.CreateInitalizeCollectionMethod(type), proxyTypeBuilder.BaseGetters, proxyTypeBuilder.BaseSetters, workspace); foreach (EdmMember lazyLoadMember in proxyTypeBuilder.LazyLoadMembers) { EntityProxyFactory.InterceptMember(lazyLoadMember, type, proxyTypeInfo); } EntityProxyFactory.SetResetFKSetterFlagDelegate(type, proxyTypeInfo); EntityProxyFactory.SetCompareByteArraysDelegate(type); } else { proxyTypeInfo = (EntityProxyTypeInfo)null; } return(proxyTypeInfo); }
// <summary> // Return proxy type information for the specified O-Space EntityType. // </summary> // <param name="ospaceEntityType"> EntityType in O-Space that represents the CLR type to be proxied. Must not be null. </param> // <returns> A non-null EntityProxyTypeInfo instance that contains information about the type of proxy for the specified O-Space EntityType; or null if no proxy can be created for the specified type. </returns> internal static EntityProxyTypeInfo GetProxyType(ClrEntityType ospaceEntityType, MetadataWorkspace workspace) { DebugCheck.NotNull(ospaceEntityType); DebugCheck.NotNull(workspace); Debug.Assert(ospaceEntityType.DataSpace == DataSpace.OSpace, "ospaceEntityType.DataSpace must be OSpace"); EntityProxyTypeInfo proxyTypeInfo = null; // Check if an entry for the proxy type already exists. if (TryGetProxyType(ospaceEntityType.ClrType, ospaceEntityType.CSpaceTypeName, out proxyTypeInfo)) { if (proxyTypeInfo != null) { proxyTypeInfo.ValidateType(ospaceEntityType); } return(proxyTypeInfo); } // No entry found, may need to create one. // Acquire an upgradeable read lock so that: // 1. Other readers aren't blocked while the second existence check is performed. // 2. Other threads that may have also detected the absence of an entry block while the first thread handles proxy type creation. _typeMapLock.EnterUpgradeableReadLock(); try { return(TryCreateProxyType(ospaceEntityType, workspace)); } finally { _typeMapLock.ExitUpgradeableReadLock(); } }
public void ValidateType(ClrEntityType ospaceEntityType) { if (ospaceEntityType != this._entityType && ospaceEntityType.HashedDescription != this._entityType.HashedDescription) { throw new InvalidOperationException(Strings.EntityProxyTypeInfo_DuplicateOSpaceType((object)ospaceEntityType.ClrType.FullName)); } }
public void ValidateType(ClrEntityType ospaceEntityType) { if (ospaceEntityType != _entityType && ospaceEntityType.HashedDescription != _entityType.HashedDescription) { Debug.Assert(ospaceEntityType.ClrType == _entityType.ClrType); throw EntityUtil.DuplicateTypeForProxyType(ospaceEntityType.ClrType); } }
public ProxyTypeBuilder(ClrEntityType ospaceEntityType) { _ospaceEntityType = ospaceEntityType; _baseImplementor = new BaseProxyImplementor(); _ipocoImplementor = new IPocoImplementor(ospaceEntityType); _lazyLoadImplementor = new LazyLoadImplementor(ospaceEntityType); _dataContractImplementor = new DataContractImplementor(ospaceEntityType); _iserializableImplementor = new SerializableImplementor(ospaceEntityType); }
public void ValidateType(ClrEntityType ospaceEntityType) { if (ospaceEntityType != _entityType && ospaceEntityType.HashedDescription != _entityType.HashedDescription) { Debug.Assert(ospaceEntityType.ClrType == _entityType.ClrType); throw new InvalidOperationException(Strings.EntityProxyTypeInfo_DuplicateOSpaceType(ospaceEntityType.ClrType.FullName)); } }
internal EntityProxyTypeInfo( Type proxyType, ClrEntityType ospaceEntityType, DynamicMethod initializeCollections, List <PropertyInfo> baseGetters, List <PropertyInfo> baseSetters, MetadataWorkspace workspace) { this._proxyType = proxyType; this._entityType = ospaceEntityType; this._initializeCollections = initializeCollections; foreach (AssociationType associationType in EntityProxyTypeInfo.GetAllRelationshipsForType(workspace, proxyType)) { this._navigationPropertyAssociationTypes.Add(associationType.FullName, associationType); if (associationType.Name != associationType.FullName) { this._navigationPropertyAssociationTypes.Add(associationType.Name, associationType); } } FieldInfo field = proxyType.GetField("_entityWrapper", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(object), "proxy"); ParameterExpression parameterExpression5 = Expression.Parameter(typeof(object), "value"); Func <object, object> getEntityWrapperDelegate = Expression.Lambda <Func <object, object> >((Expression)Expression.Field((Expression)Expression.Convert((Expression)parameterExpression4, field.DeclaringType), field), parameterExpression4).Compile(); this.Proxy_GetEntityWrapper = (Func <object, object>)(proxy => { IEntityWrapper entityWrapper = (IEntityWrapper)getEntityWrapperDelegate(proxy); if (entityWrapper != null && !object.ReferenceEquals(entityWrapper.Entity, proxy)) { throw new InvalidOperationException(Strings.EntityProxyTypeInfo_ProxyHasWrongWrapper); } return((object)entityWrapper); }); this.Proxy_SetEntityWrapper = ((Expression <Func <object, object, object> >)((parameterExpression1, parameterExpression2) => Expression.Assign((Expression)Expression.Field((Expression)Expression.Convert((Expression)parameterExpression4, field.DeclaringType), field), parameterExpression2))).Compile(); ParameterExpression parameterExpression6 = Expression.Parameter(typeof(string), "propertyName"); MethodInfo publicInstanceMethod1 = proxyType.GetPublicInstanceMethod("GetBasePropertyValue", typeof(string)); if (publicInstanceMethod1 != (MethodInfo)null) { this._baseGetter = Expression.Lambda <Func <object, string, object> >((Expression)Expression.Call((Expression)Expression.Convert((Expression)parameterExpression4, proxyType), publicInstanceMethod1, (Expression)parameterExpression6), parameterExpression4, parameterExpression6).Compile(); } ParameterExpression parameterExpression7 = Expression.Parameter(typeof(object), "propertyName"); MethodInfo publicInstanceMethod2 = proxyType.GetPublicInstanceMethod("SetBasePropertyValue", typeof(string), typeof(object)); if (publicInstanceMethod2 != (MethodInfo)null) { this._baseSetter = ((Expression <Action <object, string, object> >)((parameterExpression1, parameterExpression2, parameterExpression3) => Expression.Call((Expression)Expression.Convert(parameterExpression1, proxyType), publicInstanceMethod2, parameterExpression2, parameterExpression3))).Compile(); } this._propertiesWithBaseGetter = new HashSet <string>(baseGetters.Select <PropertyInfo, string>((Func <PropertyInfo, string>)(p => p.Name))); this._propertiesWithBaseSetter = new HashSet <string>(baseSetters.Select <PropertyInfo, string>((Func <PropertyInfo, string>)(p => p.Name))); this._createObject = DelegateFactory.CreateConstructor(proxyType); }
// <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, MetadataWorkspace workspace) { Debug.Assert( _typeMapLock.IsUpgradeableReadLockHeld, "EntityProxyTypeInfo.BuildType method was called without first acquiring an upgradeable read lock from _typeMapLock."); EntityProxyTypeInfo proxyTypeInfo; var proxyTypeBuilder = new ProxyTypeBuilder(ospaceEntityType); var 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. var typeAssembly = proxyType.Assembly(); if (!_proxyRuntimeAssemblies.Contains(typeAssembly)) { _proxyRuntimeAssemblies.Add(typeAssembly); AddAssemblyToResolveList(typeAssembly); } proxyTypeInfo = new EntityProxyTypeInfo( proxyType, ospaceEntityType, proxyTypeBuilder.CreateInitalizeCollectionMethod(proxyType), proxyTypeBuilder.BaseGetters, proxyTypeBuilder.BaseSetters, workspace); foreach (var member in proxyTypeBuilder.LazyLoadMembers) { InterceptMember(member, proxyType, proxyTypeInfo); } SetResetFKSetterFlagDelegate(proxyType, proxyTypeInfo); SetCompareByteArraysDelegate(proxyType); } else { proxyTypeInfo = null; } return(proxyTypeInfo); }
internal static EntityProxyTypeInfo GetProxyType( ClrEntityType ospaceEntityType, MetadataWorkspace workspace) { EntityProxyTypeInfo proxyTypeInfo = (EntityProxyTypeInfo)null; if (EntityProxyFactory.TryGetProxyType(ospaceEntityType.ClrType, ospaceEntityType.CSpaceTypeName, out proxyTypeInfo)) { proxyTypeInfo?.ValidateType(ospaceEntityType); return(proxyTypeInfo); } EntityProxyFactory._typeMapLock.EnterUpgradeableReadLock(); try { return(EntityProxyFactory.TryCreateProxyType((EntityType)ospaceEntityType, workspace)); } finally { EntityProxyFactory._typeMapLock.ExitUpgradeableReadLock(); } }
private static EntityProxyTypeInfo TryCreateProxyType( EntityType ospaceEntityType, MetadataWorkspace workspace) { ClrEntityType ospaceEntityType1 = (ClrEntityType)ospaceEntityType; Tuple <Type, string> key = new Tuple <Type, string>(ospaceEntityType1.ClrType, ospaceEntityType1.HashedDescription); EntityProxyTypeInfo entityProxyTypeInfo; if (!EntityProxyFactory._proxyNameMap.TryGetValue(key, out entityProxyTypeInfo)) { if (EntityProxyFactory.CanProxyType(ospaceEntityType)) { try { entityProxyTypeInfo = EntityProxyFactory.BuildType(EntityProxyFactory.GetDynamicModule(ospaceEntityType), ospaceEntityType1, workspace); EntityProxyFactory._typeMapLock.EnterWriteLock(); try { EntityProxyFactory._proxyNameMap[key] = entityProxyTypeInfo; if (entityProxyTypeInfo != null) { EntityProxyFactory._proxyTypeMap[entityProxyTypeInfo.ProxyType] = entityProxyTypeInfo; } } finally { EntityProxyFactory._typeMapLock.ExitWriteLock(); } } catch { EntityProxyFactory.DiscardDynamicModule(ospaceEntityType); throw; } } } return(entityProxyTypeInfo); }
/// <summary>For an OSpace EntityType returns the delegate to construct the clr instance.</summary> internal static Delegate GetConstructorDelegateForType(ClrEntityType clrType) { return(clrType.Constructor ?? (clrType.Constructor = CreateConstructor(clrType.ClrType))); }
internal EntityProxyTypeInfo( Type proxyType, ClrEntityType ospaceEntityType, DynamicMethod initializeCollections, List <PropertyInfo> baseGetters, List <PropertyInfo> baseSetters) { DebugCheck.NotNull(proxyType); _proxyType = proxyType; _entityType = ospaceEntityType; _initializeCollections = initializeCollections; _navigationPropertyAssociationTypes = new Dictionary <Tuple <string, string>, AssociationType>(); foreach (var navigationProperty in ospaceEntityType.NavigationProperties) { _navigationPropertyAssociationTypes.Add( new Tuple <string, string>( navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name), (AssociationType)navigationProperty.RelationshipType); if (navigationProperty.RelationshipType.Name != navigationProperty.RelationshipType.FullName) { // Sometimes there isn't enough metadata to have a container name // Default codegen doesn't qualify names _navigationPropertyAssociationTypes.Add( new Tuple <string, string>( navigationProperty.RelationshipType.Name, navigationProperty.ToEndMember.Name), (AssociationType)navigationProperty.RelationshipType); } } var entityWrapperField = proxyType.GetField( EntityWrapperFieldName, BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); var Object_Parameter = Expression.Parameter(typeof(object), "proxy"); var Value_Parameter = Expression.Parameter(typeof(object), "value"); Debug.Assert(entityWrapperField != null, "entityWrapperField does not exist"); // Create the Wrapper Getter var lambda = Expression.Lambda <Func <object, object> >( Expression.Field( Expression.Convert(Object_Parameter, entityWrapperField.DeclaringType), entityWrapperField), Object_Parameter); var getEntityWrapperDelegate = lambda.Compile(); Proxy_GetEntityWrapper = (object proxy) => { // This code validates that the wrapper points to the proxy that holds the wrapper. // This guards against mischief by switching this wrapper out for another one obtained // from a different object. var wrapper = ((IEntityWrapper)getEntityWrapperDelegate(proxy)); if (wrapper != null && !ReferenceEquals(wrapper.Entity, proxy)) { throw new InvalidOperationException(Strings.EntityProxyTypeInfo_ProxyHasWrongWrapper); } return(wrapper); }; // Create the Wrapper setter Proxy_SetEntityWrapper = Expression.Lambda <Func <object, object, object> >( Expression.Assign( Expression.Field( Expression.Convert(Object_Parameter, entityWrapperField.DeclaringType), entityWrapperField), Value_Parameter), Object_Parameter, Value_Parameter).Compile(); var PropertyName_Parameter = Expression.Parameter(typeof(string), "propertyName"); var baseGetterMethod = proxyType.GetMethod( "GetBasePropertyValue", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string) }, null); if (baseGetterMethod != null) { _baseGetter = Expression.Lambda <Func <object, string, object> >( Expression.Call(Expression.Convert(Object_Parameter, proxyType), baseGetterMethod, PropertyName_Parameter), Object_Parameter, PropertyName_Parameter).Compile(); } var PropertyValue_Parameter = Expression.Parameter(typeof(object), "propertyName"); var baseSetterMethod = proxyType.GetMethod( "SetBasePropertyValue", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string), typeof(object) }, null); if (baseSetterMethod != null) { _baseSetter = Expression.Lambda <Action <object, string, object> >( Expression.Call( Expression.Convert(Object_Parameter, proxyType), baseSetterMethod, PropertyName_Parameter, PropertyValue_Parameter), Object_Parameter, PropertyName_Parameter, PropertyValue_Parameter).Compile(); } _propertiesWithBaseGetter = new HashSet <string>(baseGetters.Select(p => p.Name)); _propertiesWithBaseSetter = new HashSet <string>(baseSetters.Select(p => p.Name)); _createObject = DelegateFactory.CreateConstructor(proxyType); }
internal static Func <object> GetConstructorDelegateForType(ClrEntityType clrType) { return(clrType.Constructor ?? (clrType.Constructor = DelegateFactory.CreateConstructor(clrType.ClrType))); }