/// <summary> /// Creates new instance of the type defined by this node. /// </summary> /// <param name="context">Context to evaluate expressions against.</param> /// <param name="evalContext">Current expression evaluation context.</param> /// <returns>Node's value.</returns> protected override object Get(object context, EvaluationContext evalContext) { var argValues = ResolveArguments(evalContext); var namedArgValues = ResolveNamedArguments(evalContext); if (_constructor == null) { lock (this) { if (_constructor == null) { _constructor = InitializeNode(argValues, namedArgValues); } } } var paramValues = (_isParamArray ? ReflectionUtils.PackageParamArray(argValues, _argumentCount, _paramArrayType) : argValues); var instance = _constructor.Invoke(paramValues); if (namedArgValues != null) { SetNamedArguments(instance, namedArgValues); } return instance; }
/// <summary> /// Initializes this node by caching necessary constructor and property info. /// </summary> /// <param name="argValues"></param> /// <param name="namedArgValues"></param> private SafeConstructor InitializeNode(object[] argValues, IDictionary namedArgValues) { SafeConstructor ctor = null; var objectType = GetObjectType(getText().Trim()); // cache constructor info var ci = GetBestConstructor(objectType, argValues); if (ci == null) { throw new ArgumentException( String.Format("Constructor for the type [{0}] with a specified " + "number and types of arguments does not exist.", objectType.FullName)); } var parameters = ci.GetParameters(); if (parameters.Length > 0) { var lastParameter = parameters[parameters.Length - 1]; _isParamArray = lastParameter.GetCustomAttributes(typeof (ParamArrayAttribute), false).Length > 0; if (_isParamArray) { _paramArrayType = lastParameter.ParameterType.GetElementType(); _argumentCount = parameters.Length; } } ctor = new SafeConstructor(ci); // cache named args info if (namedArgValues != null) { _namedArgs = new Hashtable(namedArgValues.Count); foreach (string name in namedArgValues.Keys) { _namedArgs[name] = Expression.ParseProperty(name); } } return ctor; }