Пример #1
0
    /// <summary>
    ///     Creates an expression tree representing the binding of the value of a property from a
    ///     materialization expression to a parameter of the constructor, factory method, etc.
    /// </summary>
    /// <param name="bindingInfo">The binding information.</param>
    /// <returns>The expression tree.</returns>
    public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
    {
        var property = ConsumedProperties[0];

        return(Expression.Call(bindingInfo.MaterializationContextExpression, MaterializationContext.GetValueBufferMethod)
               .CreateValueBufferReadValueExpression(property.ClrType, bindingInfo.GetValueBufferIndex(property), property));
    }
Пример #2
0
        static ExportVisitor()
        {
            var nameParam = new ParameterInfo { name = "Name", position = 0 };
            var valueParam = new ParameterInfo { name = "Value", position = 1 };
            var aliasParameterInfo = new ParameterBindingInfo { parameterInfo = new[] { nameParam, valueParam } };

            var functionParam = new ParameterInfo { name = "Function", position = -1 };
            var cmdletParam = new ParameterInfo { name = "Cmdlet", position = -1 };
            var aliasParam = new ParameterInfo { name = "Alias", position = -1 };
            var ipmoParameterInfo = new ParameterBindingInfo { parameterInfo = new[] { nameParam, functionParam, cmdletParam, aliasParam } };

            functionParam = new ParameterInfo { name = "Function", position = 0 };
            var exportModuleMemberInfo = new ParameterBindingInfo { parameterInfo = new[] { functionParam, cmdletParam, aliasParam } };

            s_parameterBindingInfoTable = new Dictionary<string, ParameterBindingInfo>(StringComparer.OrdinalIgnoreCase)
            {
                {"New-Alias",                                      aliasParameterInfo},
                {@"Microsoft.PowerShell.Utility\New-Alias",        aliasParameterInfo},
                {"Set-Alias",                                      aliasParameterInfo},
                {@"Microsoft.PowerShell.Utility\Set-Alias",        aliasParameterInfo},
                {"nal",                                            aliasParameterInfo},
                {"sal",                                            aliasParameterInfo},
                {"Import-Module",                                  ipmoParameterInfo},
                {@"Microsoft.PowerShell.Core\Import-Module",       ipmoParameterInfo},
                {"ipmo",                                           ipmoParameterInfo},
                {"Export-ModuleMember",                            exportModuleMemberInfo},
                {@"Microsoft.PowerShell.Core\Export-ModuleMember", exportModuleMemberInfo}
            };
        }
        private Predicate <string> GetPropertyFilter(ParameterDescriptor parameterDescriptor)
        {
            ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo;
            var ba = new BindAttribute()
            {
                Exclude = string.Join(",", bindingInfo.Exclude),
                Include = string.Join(",", bindingInfo.Include)
            };

            return(ba.IsPropertyAllowed);
        }
Пример #4
0
        public void BindingInfoProperty()
        {
            // Arrange
            Type emptyBindingInfoType = typeof(ParameterDescriptor).GetNestedType("EmptyParameterBindingInfo", BindingFlags.NonPublic);
            ParameterDescriptor pd    = GetParameterDescriptor(typeof(object), "someName");

            // Act
            ParameterBindingInfo bindingInfo = pd.BindingInfo;

            // Assert
            Assert.IsInstanceOfType(bindingInfo, emptyBindingInfoType);
        }
        public void BindingInfoProperty()
        {
            // Arrange
            ParameterDescriptor pd = GetParameterDescriptor(typeof(object), "someName");

            // Act
            ParameterBindingInfo bindingInfo = pd.BindingInfo;

            // Assert
            Assert.IsType(typeof(ParameterDescriptor).GetNestedType("EmptyParameterBindingInfo", BindingFlags.NonPublic),
                          bindingInfo);
        }
    /// <summary>
    ///     Creates an expression tree representing the binding of the value of a property from a
    ///     materialization expression to a parameter of the constructor, factory method, etc.
    /// </summary>
    /// <param name="bindingInfo">The binding information.</param>
    /// <returns>The expression tree.</returns>
    public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
    => Expression.NewArrayInit(
        typeof(object),
        _bindings.Select(
            b =>
    {
        var expression = b.BindToParameter(bindingInfo);

        if (expression.Type.IsValueType)
        {
            expression = Expression.Convert(expression, typeof(object));
        }

        return(expression);
    }));
Пример #7
0
    /// <summary>
    ///     Creates a <see cref="MethodCallExpression" /> using the given method.
    /// </summary>
    /// <param name="bindingInfo">Information needed to create the expression.</param>
    /// <returns>The expression tree.</returns>
    public override Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo)
    {
        var arguments = ParameterBindings.Select(b => b.BindToParameter(bindingInfo));

        Expression expression
            = _factoryInstance == null
                ? Expression.Call(
                  _factoryMethod,
                  arguments)
                : Expression.Call(
                  Expression.Constant(_factoryInstance),
                  _factoryMethod,
                  arguments);

        if (_factoryMethod.ReturnType != RuntimeType)
        {
            expression = Expression.Convert(expression, RuntimeType);
        }

        return(expression);
    }
Пример #8
0
        public virtual Expression CreateMaterializeExpression(
            IEntityType entityType,
            string entityInstanceName,
            Expression materializationContextExpression)
        {
            if (entityType.IsAbstract())
            {
                throw new InvalidOperationException(CoreStrings.CannotMaterializeAbstractType(entityType.DisplayName()));
            }

            var constructorBinding = (InstantiationBinding?)entityType[CoreAnnotationNames.ConstructorBinding];

            if (constructorBinding == null)
            {
                var constructorInfo = entityType.ClrType.GetDeclaredConstructor(null);

                if (constructorInfo == null)
                {
                    throw new InvalidOperationException(CoreStrings.NoParameterlessConstructor(entityType.DisplayName()));
                }

                constructorBinding = new ConstructorBinding(constructorInfo, Array.Empty <ParameterBinding>());
            }

            var bindingInfo = new ParameterBindingInfo(
                entityType,
                materializationContextExpression);

            var properties = new HashSet <IPropertyBase>(
                entityType.GetServiceProperties().Cast <IPropertyBase>()
                .Concat(
                    entityType
                    .GetProperties()
                    .Where(p => !p.IsShadowProperty())));

            foreach (var consumedProperty in constructorBinding
                     .ParameterBindings
                     .SelectMany(p => p.ConsumedProperties))
            {
                properties.Remove(consumedProperty);
            }

            var constructorExpression = constructorBinding.CreateConstructorExpression(bindingInfo);

            if (properties.Count == 0)
            {
                return(constructorExpression);
            }

            var instanceVariable = Expression.Variable(constructorBinding.RuntimeType, entityInstanceName);

            var blockExpressions
                = new List <Expression>
                {
                Expression.Assign(
                    instanceVariable,
                    constructorExpression)
                };

            var valueBufferExpression = Expression.Call(materializationContextExpression, MaterializationContext.GetValueBufferMethod);

            foreach (var property in properties)
            {
                var memberInfo = property.GetMemberInfo(forMaterialization: true, forSet: true);

                var readValueExpression
                    = property is IServiceProperty serviceProperty
                        ? serviceProperty.GetParameterBinding() !.BindToParameter(bindingInfo)
                        : valueBufferExpression.CreateValueBufferReadValueExpression(
                          memberInfo.GetMemberType(),
                          property.GetIndex(),
                          property);

                blockExpressions.Add(CreateMemberAssignment(instanceVariable, memberInfo, property, readValueExpression));
            }

            blockExpressions.Add(instanceVariable);

            return(Expression.Block(new[] { instanceVariable }, blockExpressions));
Пример #9
0
        private static Predicate <string> GetPropertyFilter(ParameterDescriptor parameterDescriptor)
        {
            ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo;

            return(propertyName => IsPropertyAllowed(propertyName, bindingInfo.Include.ToArray(), bindingInfo.Exclude.ToArray()));
        }
Пример #10
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual Expression CreateMaterializeExpression(
            IEntityType entityType,
            string entityInstanceName,
            Expression materializationExpression,
            int[] indexMap = null)
        {
            if (!entityType.HasClrType())
            {
                throw new InvalidOperationException(CoreStrings.NoClrType(entityType.DisplayName()));
            }

            if (entityType.IsAbstract())
            {
                throw new InvalidOperationException(CoreStrings.CannotMaterializeAbstractType(entityType));
            }

            var constructorBinding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];

            if (constructorBinding == null)
            {
                var constructorInfo = entityType.ClrType.GetDeclaredConstructor(null);

                if (constructorInfo == null)
                {
                    throw new InvalidOperationException(CoreStrings.NoParameterlessConstructor(entityType.DisplayName()));
                }

                constructorBinding = new DirectConstructorBinding(constructorInfo, Array.Empty <ParameterBinding>());
            }

            // This is to avoid breaks because this method used to expect ValueBuffer but now expects MaterializationContext
            var valueBufferExpression = materializationExpression;

            if (valueBufferExpression.Type == typeof(MaterializationContext))
            {
                valueBufferExpression = Expression.Call(materializationExpression, MaterializationContext.GetValueBufferMethod);
            }
            else
            {
                materializationExpression = Expression.New(MaterializationContext.ObsoleteConstructor, materializationExpression);
            }

            var bindingInfo = new ParameterBindingInfo(
                entityType,
                materializationExpression,
                indexMap);

            var properties = new HashSet <IPropertyBase>(
                entityType.GetServiceProperties().Cast <IPropertyBase>()
                .Concat(
                    entityType
                    .GetProperties()
                    .Where(p => !p.IsShadowProperty())));

            foreach (var consumedProperty in constructorBinding
                     .ParameterBindings
                     .SelectMany(p => p.ConsumedProperties))
            {
                properties.Remove(consumedProperty);
            }

            var constructorExpression = constructorBinding.CreateConstructorExpression(bindingInfo);

            if (properties.Count == 0)
            {
                return(constructorExpression);
            }

            var instanceVariable = Expression.Variable(constructorBinding.RuntimeType, entityInstanceName);

            var blockExpressions
                = new List <Expression>
                {
                Expression.Assign(
                    instanceVariable,
                    constructorExpression)
                };

            var indexerPropertyInfo = entityType.FindIndexerProperty();

            foreach (var property in properties)
            {
                var memberInfo = property.GetMemberInfo(forConstruction: true, forSet: true);

                var readValueExpression
                    = property is IServiceProperty serviceProperty
                        ? serviceProperty.GetParameterBinding().BindToParameter(bindingInfo)
                        : CreateReadValueExpression(
                          valueBufferExpression,
                          memberInfo.GetMemberType(),
                          indexMap?[property.GetIndex()] ?? property.GetIndex(),
                          property);

                blockExpressions.Add(
                    property.IsIndexedProperty()
                        ? Expression.Assign(
                        Expression.MakeIndex(
                            instanceVariable,
                            indexerPropertyInfo,
                            new[]
                {
                    Expression.Constant(property.Name)
                }),
                        readValueExpression)
                        : Expression.MakeMemberAccess(
                        instanceVariable,
                        memberInfo).Assign(
                        readValueExpression));
            }

            blockExpressions.Add(instanceVariable);

            return(Expression.Block(
                       new[]
            {
                instanceVariable
            }, blockExpressions));
        }
Пример #11
0
 /// <summary>
 ///     Creates an expression tree that represents creating an entity instance from the given binding
 ///     information. For example, this might be a <see cref="NewExpression" /> to call a constructor,
 ///     or a <see cref="MethodCallExpression" /> to call a factory method.
 /// </summary>
 /// <param name="bindingInfo">Information needed to create the expression.</param>
 /// <returns>The expression tree.</returns>
 public abstract Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo);
Пример #12
0
 /// <summary>
 ///     Creates a <see cref="NewExpression" /> that represents creating an entity instance using the given
 ///     constructor.
 /// </summary>
 /// <param name="bindingInfo">Information needed to create the expression.</param>
 /// <returns>The expression tree.</returns>
 public override Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo)
 => Expression.New(
     Constructor,
     ParameterBindings.Select(b => b.BindToParameter(bindingInfo)));
Пример #13
0
 /// <summary>
 ///     Creates an expression tree representing the binding of the value of a property from a
 ///     materialization expression to a parameter of the constructor, factory method, etc.
 /// </summary>
 /// <param name="bindingInfo">The binding information.</param>
 /// <returns>The expression tree.</returns>
 public abstract Expression BindToParameter(ParameterBindingInfo bindingInfo);
Пример #14
0
        static ExportVisitor()
        {
            var nameParam = new ParameterInfo { name = "Name", position = 0 };
            var valueParam = new ParameterInfo { name = "Value", position = 1 };
            var aliasParameterInfo = new ParameterBindingInfo { parameterInfo = new[] { nameParam, valueParam } };

            var functionParam = new ParameterInfo { name = "Function", position = -1 };
            var cmdletParam = new ParameterInfo { name = "Cmdlet", position = -1 };
            var aliasParam = new ParameterInfo { name = "Alias", position = -1 };
            var ipmoParameterInfo = new ParameterBindingInfo { parameterInfo = new[] { nameParam, functionParam, cmdletParam, aliasParam } };

            functionParam = new ParameterInfo { name = "Function", position = 0 };
            var exportModuleMemberInfo = new ParameterBindingInfo { parameterInfo = new[] { functionParam, cmdletParam, aliasParam } };

            s_parameterBindingInfoTable = new Dictionary<string, ParameterBindingInfo>(StringComparer.OrdinalIgnoreCase)
            {
                {"New-Alias",                                      aliasParameterInfo},
                {@"Microsoft.PowerShell.Utility\New-Alias",        aliasParameterInfo},
                {"Set-Alias",                                      aliasParameterInfo},
                {@"Microsoft.PowerShell.Utility\Set-Alias",        aliasParameterInfo},
                {"nal",                                            aliasParameterInfo},
                {"sal",                                            aliasParameterInfo},
                {"Import-Module",                                  ipmoParameterInfo},
                {@"Microsoft.PowerShell.Core\Import-Module",       ipmoParameterInfo},
                {"ipmo",                                           ipmoParameterInfo},
                {"Export-ModuleMember",                            exportModuleMemberInfo},
                {@"Microsoft.PowerShell.Core\Export-ModuleMember", exportModuleMemberInfo}
            };
        }
Пример #15
0
 /// <summary>
 ///     Creates an expression tree representing the binding of the value of a property from a
 ///     materialization expression to a parameter of the constructor, factory method, etc.
 /// </summary>
 /// <param name="bindingInfo">The binding information.</param>
 /// <returns>The expression tree.</returns>
 public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
 => BindToParameter(
     bindingInfo.MaterializationContextExpression,
     Expression.Constant(bindingInfo.EntityType));