public override Expression Normalize(Expression expression) { // // NB: Typical Reactor clients talk to some service APIs on a front-end service that does // further analysis of the expression tree (after deserialization) prior to sending it // to one or more query evaluator nodes. For example, a query may get split to run across // multiple nodes. Here, we bind directly to the query engine, so a few more steps are // involved to make this happen: // // - The engine stores definitions in "tuple normal form" such that all operators can be // defined as unary. E.g. t => t.Item1.Where(t.Item2) rather than (xs, f) => xs.Where(f). // - The client refers to types in the IReactive*Proxy space with async APIs but the // engine has synchronous symmetric APIs in the IReactive* space. We map types across. // var normalized = base.Normalize(expression); var res = Tupletize(normalized); var rw = new AsyncToSyncRewriter( new Dictionary <Type, Type> { { typeof(IReactiveClientProxy), typeof(IReactiveClient) }, { typeof(IReactiveDefinitionProxy), typeof(IReactiveDefinition) }, { typeof(IReactiveMetadataProxy), typeof(IReactiveMetadata) }, { typeof(IReactiveProxy), typeof(IReactive) }, }); res = rw.Rewrite(res); return(res); }
private static void AssertRewrite(Expression before, Expression after) { var rewriter = new AsyncToSyncRewriter(new Dictionary <Type, Type>()); var comparer = new ExpressionEqualityComparer(() => new Comparator()); var rewritten = rewriter.Rewrite(before); Assert.IsTrue(comparer.Equals(rewritten, after), string.Format(CultureInfo.InvariantCulture, "Expected: {0}, Actual: {1}", after, rewritten)); }
public void AsyncToSyncRewriter_InvalidSubscribeSignatureFails() { var rewriter = new AsyncToSyncRewriter(new Dictionary <Type, Type>()); Assert.ThrowsException <InvalidOperationException>( () => rewriter.Rewrite( Expression.Invoke( Expression.Parameter(typeof(Func <, ,>).MakeGenericType(AsyncObservableType, AsyncObserverType, AsyncSubscriptionType), Constants.SubscribeUri), Expression.Parameter(AsyncObservableType, "bing://xs"), Expression.Parameter(AsyncObserverType, "bing://observer") ) ) ); Assert.ThrowsException <InvalidOperationException>( () => rewriter.Rewrite( Expression.Parameter(typeof(int), Constants.SubscribeUri) ) ); }
/// <summary> /// Rewrites the expression from asynchronous reactive proxy interfaces to their synchronous counterparts. /// </summary> /// <param name="expression">The expression to rewrite to a synchronous form.</param> /// <returns>The rewritten expression using synchronous operations.</returns> public static Expression RewriteAsyncToSync(Expression expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var rw = new AsyncToSyncRewriter( new Dictionary <Type, Type> { { typeof(IReactiveClientProxy), typeof(IReactiveClient) }, { typeof(IReactiveDefinitionProxy), typeof(IReactiveDefinition) }, { typeof(IReactiveMetadataProxy), typeof(IReactiveMetadata) }, { typeof(IReactiveProxy), typeof(IReactive) }, }); return(rw.Rewrite(expression)); }