public override object ProvideValue(IServiceProvider serviceProvider)
 {
     try
     {
         var converter = new QuickConverter(Value)
         {
             V0             = V0,
             V1             = V1,
             V2             = V2,
             V3             = V3,
             V4             = V4,
             V5             = V5,
             V6             = V6,
             V7             = V7,
             V8             = V8,
             V9             = V9,
             DynamicContext = DynamicContext
         };
         var value = (converter.ProvideValue(null) as IValueConverter).Convert(null, typeof(object), null, null);
         if (value is MarkupExtension)
         {
             return((value as MarkupExtension).ProvideValue(serviceProvider));
         }
         return(value);
     }
     catch (Exception e)
     {
         EquationTokenizer.ThrowQuickConverterEvent(new MarkupExtensionExceptionEventArgs(Value, this, e));
         throw;
     }
 }
Exemple #2
0
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            try
            {
                Tuple <string, Func <object[], object[], object>, string[], DataContainer[]> func = null;
                if (Converter != null && !toFunctions.TryGetValue(Converter, out func))
                {
                    Tuple <string, Delegate, ParameterExpression[], DataContainer[]> tuple = GetLambda(Converter, false);
                    if (tuple == null)
                    {
                        return(null);
                    }

                    List <string>       parNames = new List <string>();
                    int                 pCount   = 0;
                    ParameterExpression inputP   = Expression.Parameter(typeof(object[]));
                    ParameterExpression inputV   = Expression.Parameter(typeof(object[]));
                    int[]               inds     = new int[10];
                    foreach (var par in tuple.Item3.Where(p => p.Name[0] == 'P').OrderBy(e => e.Name))
                    {
                        parNames.Add(par.Name);
                        inds[par.Name[1] - '0'] = pCount++;
                    }
                    var arguments = tuple.Item3.Select <ParameterExpression, Expression>(par =>
                    {
                        if (par.Name[0] == 'P')
                        {
                            return(Expression.ArrayIndex(inputP, Expression.Constant(inds[par.Name[1] - '0'])));
                        }
                        return(Expression.ArrayIndex(inputV, Expression.Constant((int)(par.Name[1] - '0'))));
                    });

                    Expression exp    = Expression.Call(Expression.Constant(tuple.Item2, tuple.Item2.GetType()), tuple.Item2.GetType().GetMethod("Invoke"), arguments);
                    var        result = Expression.Lambda <Func <object[], object[], object> >(exp, inputP, inputV).Compile();
                    func = new Tuple <string, Func <object[], object[], object>, string[], DataContainer[]>(tuple.Item1, result, parNames.ToArray(), tuple.Item4);

                    toFunctions.Add(Converter, func);
                }
                Tuple <string, Func <object, object[], object>, DataContainer[]>[] backFuncs = new Tuple <string, Func <object, object[], object>, DataContainer[]> [10];
                for (int i = 0; i <= 9; ++i)
                {
                    var converter = typeof(QuickMultiConverter).GetProperty("ConvertBack" + i).GetValue(this, null) as string;
                    if (String.IsNullOrWhiteSpace(converter))
                    {
                        backFuncs[i] = new Tuple <string, Func <object, object[], object>, DataContainer[]>(null, null, new DataContainer[0]);
                        continue;
                    }
                    Tuple <string, Delegate, ParameterExpression[], DataContainer[]> tuple = GetLambda(converter, true);
                    if (tuple == null)
                    {
                        backFuncs[i] = new Tuple <string, Func <object, object[], object>, DataContainer[]>(null, null, new DataContainer[0]);
                        continue;
                    }

                    ParameterExpression val = Expression.Parameter(typeof(object));
                    ParameterExpression inV = Expression.Parameter(typeof(object[]));
                    var arguments           = tuple.Item3.Select <ParameterExpression, Expression>(par =>
                    {
                        if (par.Name[0] == 'V')
                        {
                            return(Expression.ArrayIndex(inV, Expression.Constant((int)(par.Name[1] - '0'))));
                        }
                        return(val);
                    });

                    Expression exp    = Expression.Call(Expression.Constant(tuple.Item2, tuple.Item2.GetType()), tuple.Item2.GetType().GetMethod("Invoke"), arguments);
                    var        result = Expression.Lambda <Func <object, object[], object> >(exp, val, inV).Compile();
                    backFuncs[i] = new Tuple <string, Func <object, object[], object>, DataContainer[]>(tuple.Item1, result, tuple.Item4);
                }

                if (func == null)
                {
                    func = new Tuple <string, Func <object[], object[], object>, string[], DataContainer[]>(null, null, null, null);
                }

                List <object> pTypes    = new List <object>();
                List <int>    pIndicies = new List <int>();
                List <Tuple <string, Func <object, object[], object>, DataContainer[], string> > backs = new List <Tuple <string, Func <object, object[], object>, DataContainer[], string> >();
                if (func.Item3 != null)
                {
                    foreach (string name in func.Item3)
                    {
                        int index = name[1] - '0';
                        pIndicies.Add(index);
                        pTypes.Add(typeof(QuickMultiConverter).GetProperty(name + "Type").GetValue(this, null));
                        backs.Add(new Tuple <string, Func <object, object[], object>, DataContainer[], string>(backFuncs[index].Item1, backFuncs[index].Item2, backFuncs[index].Item3, typeof(QuickMultiConverter).GetProperty("ConvertBack" + name[1]).GetValue(this, null) as string));
                    }
                }

                List <object> vals = new List <object>();
                for (int i = 0; i <= 9; ++i)
                {
                    vals.Add(typeof(QuickMultiConverter).GetProperty("V" + i).GetValue(this, null));
                }

                _parameterOrder = func.Item3;

                return(new DynamicMultiConverter(func.Item2, backs.Select(t => t.Item2).ToArray(), vals.ToArray(), Converter, func.Item1, backs.Select(t => t.Item4).ToArray(), backs.Select(t => t.Item1).ToArray(), pTypes.Select(t => QuickConverter.GetType(t)).ToArray(), pIndicies.ToArray(), QuickConverter.GetType(ValueType), func.Item4, backs.SelectMany(t => t.Item3).ToArray(), ChainedConverter));
            }
            catch (Exception e)
            {
                EquationTokenizer.ThrowQuickConverterEvent(new MarkupExtensionExceptionEventArgs(Converter, this, e));
                throw;
            }
        }