/// <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)); }
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); }
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); }));
/// <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); }
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));
private static Predicate <string> GetPropertyFilter(ParameterDescriptor parameterDescriptor) { ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo; return(propertyName => IsPropertyAllowed(propertyName, bindingInfo.Include.ToArray(), bindingInfo.Exclude.ToArray())); }
/// <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)); }
/// <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);
/// <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)));
/// <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);
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} }; }
/// <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));