public GetParameterValuesAsync ( System.Web.HttpContextBase context, |
||
context | System.Web.HttpContextBase | |
type | ||
method | ||
return | Task |
public void SetUp() { _mapper1 = MockRepository.GenerateMock<IParameterMapper>(); _mapper1.Stub(arg => arg.CanMapTypeAsync(Arg<HttpContextBase>.Is.Anything, Arg<Type>.Is.Anything)).Return(false.AsCompletedTask()); _mapper2 = MockRepository.GenerateMock<IParameterMapper>(); _mapper2.Stub(arg => arg.CanMapTypeAsync(Arg<HttpContextBase>.Is.Anything, Arg<Type>.Is.Anything)).Return(true.AsCompletedTask()); _mapper2 .Stub(arg => arg.MapAsync(Arg<HttpContextBase>.Is.Anything, Arg<Type>.Is.Anything, Arg<MethodInfo>.Is.Anything, Arg<ParameterInfo>.Is.Anything)) .WhenCalled(arg => arg.ReturnValue = (MapResult.ValueMapped(100)).AsCompletedTask()) .Return(null); _mapper3 = MockRepository.GenerateMock<IParameterMapper>(); _mapper3.Stub(arg => arg.CanMapTypeAsync(Arg<HttpContextBase>.Is.Anything, Arg<Type>.Is.Anything)).Return(false.AsCompletedTask()); _retriever = new ParameterValueRetriever(new[] { _mapper1, _mapper2, _mapper3 }); _context = MockRepository.GenerateMock<HttpContextBase>(); _values = _retriever.GetParameterValuesAsync(_context, typeof(Endpoint), typeof(Endpoint).GetMethod("Method")).Result; }
public Task MapAsync(Func <IContainer> container, Type type, MethodInfo method, Routing.Route route) { container.ThrowIfNull("container"); type.ThrowIfNull("type"); method.ThrowIfNull("method"); route.ThrowIfNull("route"); bool methodReturnTypeImplementsIResponse = method.ReturnType.ImplementsInterface <IResponse>(); bool methodReturnTypeIsTaskT = method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>); bool methodReturnTypeIsVoid = method.ReturnType == typeof(void); if (methodReturnTypeImplementsIResponse) { ParameterInfo[] parameterInfos = method.GetParameters(); ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parametersParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); UnaryExpression unaryExpression = Expression.Convert( Expression.Call( Expression.Convert(instanceParameterExpression, type), method, parameterInfos.Select((arg, index) => Expression.Convert( Expression.ArrayIndex(parametersParameterExpression, Expression.Constant(index)), arg.ParameterType))), typeof(IResponse)); Func <object, object[], IResponse> @delegate = Expression.Lambda <Func <object, object[], IResponse> >(unaryExpression, instanceParameterExpression, parametersParameterExpression).Compile(); route.RespondWith( async context => { object instance; try { instance = container().GetInstance(type); } catch (Exception exception) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName), exception); } if (instance == null) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName)); } var parameterValueRetriever = new ParameterValueRetriever(_parameterMappers); object[] parameterValues = (await parameterValueRetriever.GetParameterValuesAsync(context, type, method)).ToArray(); return(@delegate(instance, parameterValues)); }, method.ReturnType); } else if (methodReturnTypeIsTaskT) { ParameterInfo[] parameterInfos = method.GetParameters(); ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parametersParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); Type methodGenericArgumentType = method.ReturnType.GetGenericArguments()[0]; MethodInfo upcastMethodInfo = typeof(TaskExtensions) .GetMethod("Upcast", BindingFlags.Static | BindingFlags.Public) .MakeGenericMethod(methodGenericArgumentType, typeof(IResponse)); UnaryExpression unaryExpression = Expression.Convert( Expression.Call( upcastMethodInfo, Expression.Call( Expression.Convert(instanceParameterExpression, type), method, parameterInfos.Select((arg, index) => Expression.Convert( Expression.ArrayIndex(parametersParameterExpression, Expression.Constant(index)), arg.ParameterType)))), upcastMethodInfo.ReturnType); Func <object, object[], Task <IResponse> > @delegate = Expression.Lambda <Func <object, object[], Task <IResponse> > >(unaryExpression, instanceParameterExpression, parametersParameterExpression).Compile(); route.RespondWith( async context => { object instance; try { instance = container().GetInstance(type); } catch (Exception exception) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName), exception); } if (instance == null) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName)); } var parameterValueRetriever = new ParameterValueRetriever(_parameterMappers); object[] parameterValues = (await parameterValueRetriever.GetParameterValuesAsync(context, type, method)).ToArray(); return(await @delegate(instance, parameterValues)); }, methodGenericArgumentType); } else if (methodReturnTypeIsVoid) { ParameterInfo[] parameterInfos = method.GetParameters(); ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parametersParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); MethodCallExpression methodCallExpression = Expression.Call( Expression.Convert(instanceParameterExpression, type), method, parameterInfos.Select((arg, index) => Expression.Convert( Expression.ArrayIndex(parametersParameterExpression, Expression.Constant(index)), arg.ParameterType))); Action <object, object[]> @delegate = Expression.Lambda <Action <object, object[]> >(methodCallExpression, instanceParameterExpression, parametersParameterExpression).Compile(); route.RespondWithNoContent( async context => { object instance; try { instance = container().GetInstance(type); } catch (Exception exception) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName), exception); } if (instance == null) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName)); } var parameterValueRetriever = new ParameterValueRetriever(_parameterMappers); object[] parameterValues = (await parameterValueRetriever.GetParameterValuesAsync(context, type, method)).ToArray(); @delegate(instance, parameterValues); }); } else { throw new ApplicationException(String.Format("The return type of {0}.{1} must implement {2} or be a {3} whose generic type argument implements {2}.", type.FullName, method.Name, typeof(IResponse).Name, typeof(Task <>))); } return(Task.Factory.Empty()); }
public Task MapAsync(Func<IContainer> container, Type type, MethodInfo method, Routing.Route route) { container.ThrowIfNull("container"); type.ThrowIfNull("type"); method.ThrowIfNull("method"); route.ThrowIfNull("route"); bool methodReturnTypeImplementsIResponse = method.ReturnType.ImplementsInterface<IResponse>(); bool methodReturnTypeIsTaskT = method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>); bool methodReturnTypeIsVoid = method.ReturnType == typeof(void); if (methodReturnTypeImplementsIResponse) { ParameterInfo[] parameterInfos = method.GetParameters(); ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parametersParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); UnaryExpression unaryExpression = Expression.Convert( Expression.Call( Expression.Convert(instanceParameterExpression, type), method, parameterInfos.Select((arg, index) => Expression.Convert( Expression.ArrayIndex(parametersParameterExpression, Expression.Constant(index)), arg.ParameterType))), typeof(IResponse)); Func<object, object[], IResponse> @delegate = Expression.Lambda<Func<object, object[], IResponse>>(unaryExpression, instanceParameterExpression, parametersParameterExpression).Compile(); route.RespondWith( async context => { object instance; try { instance = container().GetInstance(type); } catch (Exception exception) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName), exception); } if (instance == null) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName)); } var parameterValueRetriever = new ParameterValueRetriever(_parameterMappers); object[] parameterValues = (await parameterValueRetriever.GetParameterValuesAsync(context, type, method)).ToArray(); var mappedDelegateContexts = new List<IMappedDelegateContext>(); try { mappedDelegateContexts.AddRange(_contextFactories.Select(arg => arg.CreateContext(context, type, method)).Where(arg => arg != null)); IResponse response = @delegate(instance, parameterValues); foreach (IMappedDelegateContext mappedDelegateContext in mappedDelegateContexts) { mappedDelegateContext.Complete(); } return response; } finally { foreach (IMappedDelegateContext mappedDelegateContext in mappedDelegateContexts) { mappedDelegateContext.Dispose(); } } }, method.ReturnType); } else if (methodReturnTypeIsTaskT) { ParameterInfo[] parameterInfos = method.GetParameters(); ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parametersParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); Type methodGenericArgumentType = method.ReturnType.GetGenericArguments()[0]; MethodInfo upcastMethodInfo = typeof(TaskExtensions) .GetMethod("Upcast", BindingFlags.Static | BindingFlags.Public) .MakeGenericMethod(methodGenericArgumentType, typeof(IResponse)); UnaryExpression unaryExpression = Expression.Convert( Expression.Call( upcastMethodInfo, Expression.Call( Expression.Convert(instanceParameterExpression, type), method, parameterInfos.Select((arg, index) => Expression.Convert( Expression.ArrayIndex(parametersParameterExpression, Expression.Constant(index)), arg.ParameterType)))), upcastMethodInfo.ReturnType); Func<object, object[], Task<IResponse>> @delegate = Expression.Lambda<Func<object, object[], Task<IResponse>>>(unaryExpression, instanceParameterExpression, parametersParameterExpression).Compile(); route.RespondWith( async context => { object instance; try { instance = container().GetInstance(type); } catch (Exception exception) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName), exception); } if (instance == null) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName)); } var parameterValueRetriever = new ParameterValueRetriever(_parameterMappers); object[] parameterValues = (await parameterValueRetriever.GetParameterValuesAsync(context, type, method)).ToArray(); var mappedDelegateContexts = new List<IMappedDelegateContext>(); try { mappedDelegateContexts.AddRange(_contextFactories.Select(arg => arg.CreateContext(context, type, method)).Where(arg => arg != null)); IResponse response = await @delegate(instance, parameterValues); foreach (IMappedDelegateContext mappedDelegateContext in mappedDelegateContexts) { mappedDelegateContext.Complete(); } return response; } finally { foreach (IMappedDelegateContext mappedDelegateContext in mappedDelegateContexts) { mappedDelegateContext.Dispose(); } } }, methodGenericArgumentType); } else if (methodReturnTypeIsVoid) { ParameterInfo[] parameterInfos = method.GetParameters(); ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parametersParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); MethodCallExpression methodCallExpression = Expression.Call( Expression.Convert(instanceParameterExpression, type), method, parameterInfos.Select((arg, index) => Expression.Convert( Expression.ArrayIndex(parametersParameterExpression, Expression.Constant(index)), arg.ParameterType))); Action<object, object[]> @delegate = Expression.Lambda<Action<object, object[]>>(methodCallExpression, instanceParameterExpression, parametersParameterExpression).Compile(); route.RespondWithNoContent( async context => { object instance; try { instance = container().GetInstance(type); } catch (Exception exception) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName), exception); } if (instance == null) { throw new ApplicationException(String.Format("Unable to resolve instance of type {0}.", type.FullName)); } var parameterValueRetriever = new ParameterValueRetriever(_parameterMappers); object[] parameterValues = (await parameterValueRetriever.GetParameterValuesAsync(context, type, method)).ToArray(); var mappedDelegateContexts = new List<IMappedDelegateContext>(); try { mappedDelegateContexts.AddRange(_contextFactories.Select(arg => arg.CreateContext(context, type, method)).Where(arg => arg != null)); @delegate(instance, parameterValues); foreach (IMappedDelegateContext mappedDelegateContext in mappedDelegateContexts) { mappedDelegateContext.Complete(); } } finally { foreach (IMappedDelegateContext mappedDelegateContext in mappedDelegateContexts) { mappedDelegateContext.Dispose(); } } }); } else { throw new ApplicationException(String.Format("The return type of {0}.{1} must implement {2} or be a {3} whose generic type argument implements {2}.", type.FullName, method.Name, typeof(IResponse).Name, typeof(Task<>))); } return Task.Factory.Empty(); }