Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Builder and extensions cleanup #283

Merged
merged 4 commits into from
Apr 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions src/Microsoft.AspNet.Http.Core/Extensions/MapExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,6 @@ namespace Microsoft.AspNet.Builder
{
public static class MapExtensions
{
/// <summary>
/// If the request path starts with the given pathMatch, execute the app configured via configuration parameter instead of
/// continuing to the next component in the pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="pathMatch">The path to match</param>
/// <param name="configuration">The branch to take for positive path matches</param>
/// <returns></returns>
public static IApplicationBuilder Map([NotNull] this IApplicationBuilder app, [NotNull] string pathMatch, [NotNull] Action<IApplicationBuilder> configuration)
{
return Map(app, new PathString(pathMatch), configuration);
}

/// <summary>
/// If the request path starts with the given pathMatch, execute the app configured via configuration parameter instead of
/// continuing to the next component in the pipeline.
Expand Down
26 changes: 1 addition & 25 deletions src/Microsoft.AspNet.Http.Core/Extensions/MapWhenExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Builder.Extensions;
using Microsoft.Framework.Internal;

namespace Microsoft.AspNet.Builder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We totally need to change this namespace

{
using Microsoft.Framework.Internal;
using Predicate = Func<HttpContext, bool>;
using PredicateAsync = Func<HttpContext, Task<bool>>;

/// <summary>
/// Extension methods for the MapWhenMiddleware
Expand Down Expand Up @@ -39,28 +38,5 @@ public static IApplicationBuilder MapWhen([NotNull] this IApplicationBuilder app
};
return app.Use(next => new MapWhenMiddleware(next, options).Invoke);
}

/// <summary>
/// Branches the request pipeline based on the async result of the given predicate.
/// </summary>
/// <param name="app"></param>
/// <param name="predicate">Invoked asynchronously with the request environment to determine if the branch should be taken</param>
/// <param name="configuration">Configures a branch to take</param>
/// <returns></returns>
public static IApplicationBuilder MapWhenAsync([NotNull] this IApplicationBuilder app, [NotNull] PredicateAsync predicate, [NotNull] Action<IApplicationBuilder> configuration)
{
// create branch
var branchBuilder = app.New();
configuration(branchBuilder);
var branch = branchBuilder.Build();

// put middleware in pipeline
var options = new MapWhenOptions
{
PredicateAsync = predicate,
Branch = branch,
};
return app.Use(next => new MapWhenMiddleware(next, options).Invoke);
}
}
}
20 changes: 3 additions & 17 deletions src/Microsoft.AspNet.Http.Core/Extensions/MapWhenMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,13 @@ public MapWhenMiddleware([NotNull] RequestDelegate next, [NotNull] MapWhenOption

public async Task Invoke([NotNull] HttpContext context)
{
if (_options.Predicate != null)
if (_options.Predicate(context))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need a null check anymore? The setter for this property doesn't seem to guard against null.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NotNull guard is here:
https://github.com/aspnet/HttpAbstractions/pull/283/files#diff-93bfbc9b10d86e70f618ce3182ccfbeaL27

It used to check before because there were two different options, sync or async.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a guard on the method, not on the actual options class. Someone can still go to the options and make it null, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With effort. They would have to do app.Use(next => new MapWhenMiddleware(next, options).Invoke); since we don't provide an extension that takes the options directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, true. Can we add a [NotNull] to the setter anyway? That way there would be no doubt.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

{
if (_options.Predicate(context))
{
await _options.Branch(context);
}
else
{
await _next(context);
}
await _options.Branch(context);
}
else
{
if (await _options.PredicateAsync(context))
{
await _options.Branch(context);
}
else
{
await _next(context);
}
await _next(context);
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/Microsoft.AspNet.Http.Core/Extensions/MapWhenOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Internal;

namespace Microsoft.AspNet.Builder.Extensions
{
Expand All @@ -15,12 +16,12 @@ public class MapWhenOptions
/// <summary>
/// The user callback that determines if the branch should be taken
/// </summary>
public Func<HttpContext, bool> Predicate { get; set; }

/// <summary>
/// The async user callback that determines if the branch should be taken
/// </summary>
public Func<HttpContext, Task<bool>> PredicateAsync { get; set; }
public Func<HttpContext, bool> Predicate
{
get;
[param: NotNull]
set;
}

/// <summary>
/// The branch taken for a positive match
Expand Down
20 changes: 0 additions & 20 deletions src/Microsoft.AspNet.Http.Core/Extensions/RunExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,5 @@ public static void Run([NotNull] this IApplicationBuilder app, [NotNull] Request
{
app.Use(_ => handler);
}

public static void Run<TService1>(this IApplicationBuilder app, Func<HttpContext, TService1, Task> handler)
{
app.Use<TService1>((ctx, _, s1) => handler(ctx, s1));
}

public static void Run<TService1, TService2>(this IApplicationBuilder app, Func<HttpContext, TService1, TService2, Task> handler)
{
app.Use<TService1, TService2>((ctx, _, s1, s2) => handler(ctx, s1, s2));
}

public static void Run<TService1, TService2, TService3>(this IApplicationBuilder app, Func<HttpContext, TService1, TService2, TService3, Task> handler)
{
app.Use<TService1, TService2, TService3>((ctx, _, s1, s2, s3) => handler(ctx, s1, s2, s3));
}

public static void Run<TService1, TService2, TService3, TService4>(this IApplicationBuilder app, Func<HttpContext, TService1, TService2, TService3, TService4, Task> handler)
{
app.Use<TService1, TService2, TService3, TService4>((ctx, _, s1, s2, s3, s4) => handler(ctx, s1, s2, s3, s4));
}
}
}
4 changes: 2 additions & 2 deletions src/Microsoft.AspNet.Http.Core/IApplicationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ public interface IApplicationBuilder
{
IServiceProvider ApplicationServices { get; set; }

object Server { get; set; }
object Server { get; }

IDictionary<string, object> Properties { get; set; }
IDictionary<string, object> Properties { get; }

IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);

Expand Down
18 changes: 18 additions & 0 deletions src/Microsoft.AspNet.Http.Core/PathString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,5 +236,23 @@ public override int GetHashCode()
{
return left.Add(right);
}

/// <summary>
/// Implicitly creates a new PathString from the given string.
/// </summary>
/// <param name="s"></param>
public static implicit operator PathString(string s)
{
return new PathString(s);
}

/// <summary>
/// Implicitly calls ToString().
/// </summary>
/// <param name="path"></param>
public static implicit operator string(PathString path)
{
return path.ToString();
}
}
}
12 changes: 7 additions & 5 deletions src/Microsoft.AspNet.Http/ApplicationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public ApplicationBuilder(IServiceProvider serviceProvider)
ApplicationServices = serviceProvider;
}

public ApplicationBuilder(IServiceProvider serviceProvider, object server)
: this(serviceProvider)
{
SetProperty(Constants.BuilderProperties.ServerInformation, server);
}

private ApplicationBuilder(ApplicationBuilder builder)
{
Properties = builder.Properties;
Expand All @@ -42,13 +48,9 @@ public object Server
{
return GetProperty<object>(Constants.BuilderProperties.ServerInformation);
}
set
{
SetProperty<object>(Constants.BuilderProperties.ServerInformation, value);
}
}

public IDictionary<string, object> Properties { get; set; }
public IDictionary<string, object> Properties { get; }

private T GetProperty<T>(string key)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public void ChainedRoutes_Success()
var builder = new ApplicationBuilder(serviceProvider: null);
builder.Map("/route1", map =>
{
map.Map((string)"/subroute1", UseSuccess);
map.Map("/subroute1", UseSuccess);
map.Run(NotImplemented);
});
builder.Map("/route2/subroute2", UseSuccess);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ namespace Microsoft.AspNet.Builder.Extensions
public class MapPredicateMiddlewareTests
{
private static readonly Predicate NotImplementedPredicate = new Predicate(envionment => { throw new NotImplementedException(); });
private static readonly PredicateAsync NotImplementedPredicateAsync = new PredicateAsync(envionment => { throw new NotImplementedException(); });

private static Task Success(HttpContext context)
{
Expand Down Expand Up @@ -49,16 +48,6 @@ private bool FalsePredicate(HttpContext context)
return false;
}

private Task<bool> TruePredicateAsync(HttpContext context)
{
return Task.FromResult<bool>(true);
}

private Task<bool> FalsePredicateAsync(HttpContext context)
{
return Task.FromResult<bool>(false);
}

[Fact]
public void NullArguments_ArgumentNullException()
{
Expand Down Expand Up @@ -113,31 +102,6 @@ public void PredicateFalseAction_PassThrough()
Assert.Equal(200, context.Response.StatusCode);
}

[Fact]
public void PredicateAsyncTrueAction_BranchTaken()
{
HttpContext context = CreateRequest();
var builder = new ApplicationBuilder(serviceProvider: null);
builder.MapWhenAsync(TruePredicateAsync, UseSuccess);
var app = builder.Build();
app.Invoke(context).Wait();

Assert.Equal(200, context.Response.StatusCode);
}

[Fact]
public void PredicateAsyncFalseAction_PassThrough()
{
HttpContext context = CreateRequest();
var builder = new ApplicationBuilder(serviceProvider: null);
builder.MapWhenAsync(FalsePredicateAsync, UseNotImplemented);
builder.Run(Success);
var app = builder.Build();
app.Invoke(context).Wait();

Assert.Equal(200, context.Response.StatusCode);
}

[Fact]
public void ChainedPredicates_Success()
{
Expand All @@ -155,23 +119,6 @@ public void ChainedPredicates_Success()
Assert.Equal(200, context.Response.StatusCode);
}

[Fact]
public void ChainedPredicatesAsync_Success()
{
var builder = new ApplicationBuilder(serviceProvider: null);
builder.MapWhenAsync(TruePredicateAsync, map1 =>
{
map1.MapWhenAsync((PredicateAsync)FalsePredicateAsync, UseNotImplemented);
map1.MapWhenAsync((PredicateAsync)TruePredicateAsync, map2 => map2.MapWhenAsync((PredicateAsync)TruePredicateAsync, UseSuccess));
map1.Run(NotImplemented);
});
var app = builder.Build();

HttpContext context = CreateRequest();
app.Invoke(context).Wait();
Assert.Equal(200, context.Response.StatusCode);
}

private HttpContext CreateRequest()
{
HttpContext context = new DefaultHttpContext();
Expand Down