private bool TryGetOrActivate <TSource, TDest, TParam1, TParam2>(TParam1 param1, TParam2 param2, Func <ISelectExpression <TSource, TDest, TParam1, TParam2> > activator, out Expression <Func <TSource, TDest> > expression) { PairId id = PairId.GetId <TSource, TDest>(); Dictionary <PairId, LambdaExpression> expressions = GetOrAddParamExpressionsDictionary(param1, param2, add: false); Delegate factoryDelegate; LambdaExpression lambdaExpression; if (expressions != null && expressions.TryGetValue(id, out lambdaExpression)) { expression = (Expression <Func <TSource, TDest> >)lambdaExpression; return(true); } else if (_dynamicExpressionFactories.TryGetValue(id, out factoryDelegate)) { expression = ((Func <TParam1, TParam2, Expression <Func <TSource, TDest> > >)factoryDelegate)(param1, param2); return(true); } lock (_sync) { expressions = expressions ?? GetOrAddParamExpressionsDictionary(param1, param2, add: true); if (expressions.TryGetValue(id, out lambdaExpression)) { expression = (Expression <Func <TSource, TDest> >)lambdaExpression; return(true); } Func <TParam1, TParam2, Expression <Func <TSource, TDest> > > factory; if (_expressionFactories.TryGetValue(id, out factoryDelegate)) { factory = (Func <TParam1, TParam2, Expression <Func <TSource, TDest> > >)factoryDelegate; expression = factory(param1, param2); expressions.Add(id, expression); TryRemoveFactory(id); return(true); } if (_dynamicExpressionFactories.TryGetValue(id, out factoryDelegate)) { factory = (Func <TParam1, TParam2, Expression <Func <TSource, TDest> > >)factoryDelegate; expression = factory(param1, param2); return(true); } if (activator != null) { ISelectExpression <TSource, TDest, TParam1, TParam2> selectResolver = activator(); factory = selectResolver.GetSelectExpression; if (selectResolver is ISelectDynamicExpression <TSource, TDest, TParam1, TParam2> ) { _dynamicExpressionFactories.Add(id, factory); expression = factory(param1, param2); return(true); } else { _expressionFactories.Add(id, factory); expression = factory(param1, param2); expressions.Add(id, expression); TryRemoveFactory(id); return(true); } } } expression = null; return(false); }
private void TryRemoveFactory(PairId id) { }
public void RegisterAll(object mapper, Type mapperType, Type[] implementedInterfaces) { Type selectExpressionType = typeof(ISelectExpression <,>); Type dynamicSelectExpressionType = typeof(ISelectDynamicExpression <,>); var selectExpressions = implementedInterfaces.Where(i => i.GUID == selectExpressionType.GUID || i.GUID == dynamicSelectExpressionType.GUID) .Select(i => { var genericArgs = i.GetGenericArguments(); return(new { InterfaceType = i, GenericArguments = genericArgs, PairId = PairId.GetId(genericArgs[0], genericArgs[1]) }); }) .GroupBy(i => i.PairId) .Select( g => g.FirstOrDefault(i => i.InterfaceType.GUID == dynamicSelectExpressionType.GUID) ?? g.First(i => i.InterfaceType.GUID == selectExpressionType.GUID) ) .Select(interfaceDescription => { var methodInfo = mapperType.GetInterfaceMap(interfaceDescription.InterfaceType).InterfaceMethods.SingleOrDefault() ?? interfaceDescription.InterfaceType.GetInterfaces().SelectMany(i => mapperType.GetInterfaceMap(i).TargetMethods).Single(); Type delegateType = typeof(Func <>).MakeGenericType( typeof(Expression <>).MakeGenericType( typeof(Func <,>).MakeGenericType(interfaceDescription.PairId.SourceId, interfaceDescription.PairId.DestId) ) ); var factoryDelegate = Delegate.CreateDelegate(delegateType, mapper, methodInfo, true); return(new { InterfaceType = interfaceDescription.InterfaceType, PairId = interfaceDescription.PairId, FactoryDelegate = factoryDelegate }); }) .ToList(); lock (_sync) { foreach (var selectExpression in selectExpressions) { Dictionary <PairId, Delegate> cacheDictionary; if (selectExpression.InterfaceType.GUID == dynamicSelectExpressionType.GUID) { cacheDictionary = _dynamicExpressionFactories; } else if (selectExpression.InterfaceType.GUID == selectExpressionType.GUID) { cacheDictionary = _expressionFactories; } else { throw new NotSupportedException(String.Format("The interface {0} caching is not supported.", selectExpression.InterfaceType.FullName)); } if (cacheDictionary.ContainsKey(selectExpression.PairId)) { cacheDictionary[selectExpression.PairId] = selectExpression.FactoryDelegate; } else { cacheDictionary.Add(selectExpression.PairId, selectExpression.FactoryDelegate); } } } }