コード例 #1
0
        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);
        }
コード例 #2
0
        // <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();
            }
        }
コード例 #3
0
 public void ValidateType(ClrEntityType ospaceEntityType)
 {
     if (ospaceEntityType != this._entityType && ospaceEntityType.HashedDescription != this._entityType.HashedDescription)
     {
         throw new InvalidOperationException(Strings.EntityProxyTypeInfo_DuplicateOSpaceType((object)ospaceEntityType.ClrType.FullName));
     }
 }
コード例 #4
0
 public void ValidateType(ClrEntityType ospaceEntityType)
 {
     if (ospaceEntityType != _entityType && ospaceEntityType.HashedDescription != _entityType.HashedDescription)
     {
         Debug.Assert(ospaceEntityType.ClrType == _entityType.ClrType);
         throw EntityUtil.DuplicateTypeForProxyType(ospaceEntityType.ClrType);
     }
 }
コード例 #5
0
 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);
 }
コード例 #6
0
 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));
     }
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        // <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);
        }
コード例 #9
0
        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();
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
 /// <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)));
 }
コード例 #12
0
        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);
        }
コード例 #13
0
 internal static Func <object> GetConstructorDelegateForType(ClrEntityType clrType)
 {
     return(clrType.Constructor ?? (clrType.Constructor = DelegateFactory.CreateConstructor(clrType.ClrType)));
 }