예제 #1
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);
        }
예제 #2
0
 /// <summary>
 /// Creates an instance with an empty constructor.
 /// </summary>
 /// <param name="type">The type</param>
 /// <param name="constructor">The constructor info</param>
 /// <returns>The instance created</returns>
 public object CreateInstanceWithEmptyConstructor(Type type, ConstructorInfo constructor)
 {
     if (this.FactoryCache.TryGetValue(type, out Func <object> factory))
     {
         return(factory());
     }
     else
     {
         factory            = DelegateFactory.CreateConstructor <object>(type, constructor);
         FactoryCache[type] = factory;
         return(factory());
     }
 }
예제 #3
0
        public void CreateConstructorInternal()
        {
            Type                 type  = typeof(InternalClass);
            Stopwatch            watch = Stopwatch.StartNew();
            LateBoundConstructor c     = DelegateFactory.CreateConstructor(type);

            watch.Stop();
            Console.WriteLine("Time: {0}ms", watch.ElapsedMilliseconds);

            Assert.IsNotNull(c);

            object o = c.Invoke();

            Assert.IsNotNull(o);
            Assert.IsTrue(o.GetType() == type);
        }
예제 #4
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);
        }
예제 #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TypeAccessor"/> class.
 /// </summary>
 /// <param name="type">The <see cref="Type"/> this accessor is for.</param>
 public TypeAccessor(Type type)
 {
     _type = type;
     _lateBoundConstructor = new Lazy <LateBoundConstructor>(() => DelegateFactory.CreateConstructor(_type));
 }