public bool TryBuildExpression(IBuildContext buildContext, ILifetime lifetime, out Expression expression, out Exception error) { var type = buildContext.Key.Type.Descriptor(); var keyComparer = buildContext.Key.Tag as IComparer <Key>; var elementType = type.GetElementType(); if (elementType == null) { throw new BuildExpressionException($"Unsupported array type {type}.", null); } var allKeys = GetKeys(buildContext.Container, elementType); if (keyComparer != null) { allKeys = allKeys.OrderBy(i => i, keyComparer); } var keys = allKeys.ToArray(); var expressions = new Expression[keys.Length]; for (var i = 0; i < keys.Length; i++) { var context = buildContext.CreateChild(keys[i], buildContext.Container); expressions[i] = context.CreateExpression(); } expression = Expression.NewArrayInit(elementType, expressions); error = default(Exception); return(true); }
private Expression CreateDependencyExpression(Key key, [CanBeNull] Expression containerExpression, DefaultExpression defaultExpression) { if (Equals(key, ContextKey)) { return(CreateNewContextExpression()); } var selectedContainer = containerExpression != null?SelectedContainer(Visit(containerExpression) ?? throw InvalidExpressionError) : _container; return(_buildContext.CreateChild(key, selectedContainer).CreateExpression(defaultExpression)); }
private Expression CreateDependencyExpression(Key key, [CanBeNull] Expression containerExpression) { if (Equals(key, ContextKey)) { return(CreateNewContextExpression()); } var selectedContainer = containerExpression != null?SelectedContainer(containerExpression) : _container; return(_buildContext.CreateChild(key, selectedContainer).DependencyExpression); }
private static Expression CreateSwitchCases(IBuildContext buildContext, Key[] keys, Type elementType, ParameterExpression positionVar) { var cases = new SwitchCase[keys.Length]; for (var i = 0; i < keys.Length; i++) { var context = buildContext.CreateChild(keys[i], buildContext.Container); cases[i] = Expression.SwitchCase(Expression.Convert(context.CreateExpression(), elementType), Expression.Constant(i)); } return(Expression.Switch(positionVar, CreateDefault(elementType), cases)); }
public bool TryBuildExpression(IBuildContext buildContext, ILifetime lifetime, out Expression expression, out Exception error) { var resolvedKey = _keyResolver(buildContext.Key); buildContext.CreateChild(resolvedKey, buildContext.Container); var type = resolvedKey.Type; var hasExpression = new AutowiringDependency(type, buildContext.AutowiringStrategy).TryBuildExpression(buildContext, lifetime, out expression, out error); if (_options.HasFlag(Options.ResolveArgs)) { var argsResolverType = ArgsResolverDescriptor.MakeGenericType(type).Descriptor(); var ctor = argsResolverType.GetDeclaredConstructors().Single(i => i.GetParameters().Length == 1); var resolverVar = Expression.Variable(argsResolverType.Type); var fallbackExpression = expression; if (!hasExpression) { if (_options.HasFlag(Options.ResolveDefaults) && type.Descriptor().IsValueType()) { fallbackExpression = Expression.Default(type); } else { fallbackExpression = Expression.Block( Expression.Throw( Expression.Constant( new InvalidOperationException($"Cannot find a dependency for {buildContext.Key} in {buildContext.Container}. Try passing an argument of corresponding type assignable to {type.GetShortName()} via one of a Func<> arguments..\n{buildContext}"))), Expression.Default(type)); } } expression = Expression.Block( new[] { resolverVar }, Expression.Assign(resolverVar, Expression.New(ctor, buildContext.ArgsParameter)), Expression.Condition( Expression.Field(resolverVar, nameof(ArgsResolver <object> .HasValue)), Expression.Field(resolverVar, nameof(ArgsResolver <object> .Value)), fallbackExpression) ); return(true); } if (_options.HasFlag(Options.ResolveDefaults) && type.Descriptor().IsValueType()) { expression = Expression.Default(type); error = default(Exception); return(true); } return(true); }
public IEnumerable <Expression> GetParametersExpressions(IBuildContext buildContext) { for (var parameterPosition = 0; parameterPosition < _parametersExpressions.Length; parameterPosition++) { var param = _parameters[parameterPosition]; if (param.IsOut) { if (param.ParameterType.HasElementType) { var type = param.ParameterType.GetElementType(); if (type != null) { var outParam = Expression.Parameter(type); buildContext.AddParameter(outParam); yield return(outParam); continue; } } } var expression = _parametersExpressions[parameterPosition]; if (expression != null) { yield return(expression); } else { var key = new Key(param.ParameterType); Expression defaultExpression; if (param.IsOptional) { if (param.DefaultValue == null) { defaultExpression = Expression.Default(param.ParameterType); } else { defaultExpression = Expression.Constant(param.DefaultValue); } } else { defaultExpression = null; } yield return(buildContext.CreateChild(key, buildContext.Container).CreateExpression(defaultExpression)); } } }
private static Expression CreateConditions(IBuildContext buildContext, Key[] keys, Type elementType, ParameterExpression positionVar) { var conditionExpression = CreateDefault(elementType); for (var i = keys.Length - 1; i >= 0; i--) { var context = buildContext.CreateChild(keys[i], buildContext.Container); conditionExpression = Expression.Condition( Expression.Equal(positionVar, Expression.Constant(i)), Expression.Convert(context.CreateExpression(), elementType), conditionExpression); } return(conditionExpression); }
public IEnumerable <Expression> GetParametersExpressions(IBuildContext buildContext) { for (var parameterPosition = 0; parameterPosition < _parametersExpressions.Length; parameterPosition++) { var expression = _parametersExpressions[parameterPosition]; if (expression != null) { yield return(expression); } else { var key = new Key(_parameters[parameterPosition].ParameterType); yield return(buildContext.CreateChild(key, buildContext.Container).DependencyExpression); } } }