public ConstructorInfo GetConstructor(ISpecificTypeSettings settings) { var columnNameCounts = _columnNames.ToDictionary(k => k.Key, k => k.Value.Count); // If there are no settings configured, the settings.Type may default to typeof(object) // which is clearly not what we want. If we detect that situation, fall back to // TargetType var type = settings.Type == typeof(object) || settings.Type == null ? TargetType : settings.Type; if (type.IsAbstract || type.IsInterface) { throw MapCompilerException.UnconstructableAbstractType(type); } return((settings.ConstructorFinder ?? BestMatchConstructorFinder.GetDefaultInstance()) .FindBestMatch(_context.Provider, settings.Constructor, type, columnNameCounts)); }
private ConstructedValueExpression GetConstructorCallExpression(MapTypeContext context, ISpecificTypeSettings specificTypeSettings, ParameterExpression instanceVar) { var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); var constructor = context.GetConstructor(specificTypeSettings); var parameters = constructor.GetParameters(); var args = new Expression[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; var name = parameter.Name.ToLowerInvariant(); var substate = context.GetSubstateForProperty(name, parameter, parameter.ParameterType); // Compile an expression to get a value for this argument. If we don't have, it, // get a default expression for this type. We should have it in theory, because the // constructor finder shouldn't have given us a constructor which contains // parameters we don't have values for. var expr = _values.Compile(substate); if (expr.FinalValue == null || expr.IsNothing) { args[i] = parameter.ParameterType.GetDefaultValueExpression(); continue; } args[i] = expr.FinalValue; expressions.AddRange(expr.Expressions); variables.AddRange(expr.Variables); } // Call the constructor with the given args list expressions.Add( Expression.Assign(instanceVar, Expression.New(constructor, args) ) ); return(new ConstructedValueExpression(expressions, instanceVar, variables)); }
private ConstructedValueExpression AddInstantiationExpressionForSpecificType(MapTypeContext context, ISpecificTypeSettings specificType, ParameterExpression instanceVar) { // If we have a factory method, invoke that to get the instance, otherwise fall back // to finding and calling a suitable constructor var factory = specificType.GetFactory(); if (factory != null) { return(AddFactoryMethodCallExpression(context, factory, instanceVar)); } return(GetConstructorCallExpression(context, specificType, instanceVar)); }
public void AddType(ISpecificTypeSettings <T> specific) { _subclasses.Add(specific); }