0

This would be interesting:

app.UseWhenElse(
    context => context.condition(), 
    applicationBuilder => { /* Condition is true */ }, 
    applicationBuilder => { /* Condition is false */ }
});

This would allow me to do conditional routing based and handle both branches in one middleware thingie. But it doesn't exist. So I have to use this ugly construction:

app.UseWhen(
    context => context.condition(), 
    applicationBuilder => { /* Condition is true */ }
});
app.UseWhen(
    context => !context.condition(), 
    applicationBuilder => { /* Condition is false */ }
});

Now, the problem is that context.condition() gets called twice here, and this is a method, not a value. I don't want this method to execute twice so I'm considering writing an UseWhenElse() myself. But am I reinventing the wheel?

jps
  • 20,041
  • 15
  • 75
  • 79
Wim ten Brink
  • 25,901
  • 20
  • 83
  • 149
  • 5
    UseWhen is just an extension method, so why not write your own? I'd say it would have taken less time than writing this question. – Peter B Jan 05 '23 at 14:38
  • @PeterB Well, building my own is easy, but it feels to me that someone must have had the same problem before. So it's weird if there's no existing solution already. As I said, I might be reinventing the wheel by making my own implementation. – Wim ten Brink Jan 05 '23 at 15:13

1 Answers1

2

I guess it would look something like this:

public static IApplicationBuilder UseWhenElse(this IApplicationBuilder    app,
                                              Func<HttpContext, bool>     predicate,
                                              Action<IApplicationBuilder> trueConfig,
                                              Action<IApplicationBuilder> elseConfig) {
    if (app == null) {
        throw new ArgumentNullException(nameof(app));
    }
    if (predicate == null) {
        throw new ArgumentNullException(nameof(predicate));
    }
    if (trueConfig == null) {
        throw new ArgumentNullException(nameof(trueConfig));
    }
    if (elseConfig == null) {
        throw new ArgumentNullException(nameof(elseConfig));
    }

    var trueBranchBuilder = app.New();
    trueConfig(trueBranchBuilder);

    var elseBranchBuilder = app.New();
    elseConfig(elseBranchBuilder);

    return app.Use(main => {
        trueBranchBuilder.Run(main);
        var trueBranch = trueBranchBuilder.Build();

        elseBranchBuilder.Run(main);
        var elseBranch = elseBranchBuilder.Build();

        return context => predicate(context) ? trueBranch(context) : elseBranch(context);
    });
}

Haven't tested it though, let me know if it works

theemee
  • 769
  • 2
  • 10