Startup experience (#442)

Addresses #437 and #440
This commit is contained in:
Jass Bagga 2017-09-11 15:10:33 -07:00 committed by GitHub
parent 6b2ccdead8
commit a9b47f6722
9 changed files with 174 additions and 52 deletions

View File

@ -1,9 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Dispatcher;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
@ -17,6 +15,7 @@ namespace DispatcherSample
{
services.AddSingleton<UrlGenerator>();
services.AddSingleton<RouteValueAddressTable>();
services.AddDispatcher();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
@ -27,47 +26,7 @@ namespace DispatcherSample
await next.Invoke();
});
var dictionary = new Dictionary<string, DispatcherFeature>
{
{
"/example",
new DispatcherFeature
{
Endpoint = new DispatcherEndpoint("example"),
RequestDelegate = async (context) =>
{
await context.Response.WriteAsync("Hello from the example!");
}
}
},
{
"/example2",
new DispatcherFeature
{
Endpoint = new DispatcherEndpoint("example2"),
RequestDelegate = async (context) =>
{
await context.Response.WriteAsync("Hello from the second example!");
}
}
},
};
app.Use(async (context, next) =>
{
if (dictionary.TryGetValue(context.Request.Path, out var value))
{
var dispatcherFeature = new DispatcherFeature
{
Endpoint = value.Endpoint,
RequestDelegate = value.RequestDelegate
};
context.Features.Set<IDispatcherFeature>(dispatcherFeature);
await context.Response.WriteAsync("<p>Dispatch</p>");
await next.Invoke();
}
});
app.UseDispatcher();
app.Use(async (context, next) =>
{
@ -76,17 +35,11 @@ namespace DispatcherSample
});
app.Use(async (context, next) =>
{
var feature = context.Features.Get<IDispatcherFeature>();
await feature.RequestDelegate(context);
await next.Invoke();
});
app.Run(async (context) =>
{
var urlGenerator = app.ApplicationServices.GetService<UrlGenerator>();
var url = urlGenerator.GenerateURL(new RouteValueDictionary(new { Movie = "The Lion King", Character = "Mufasa" }), context);
await context.Response.WriteAsync($"<p>Generated url: {url}</p>");
await next.Invoke();
});
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Dispatcher;
namespace Microsoft.AspNetCore.Builder
{
public static class DispatcherApplicationBuilderExtensions
{
public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder)
{
builder.Properties.Add("Dispatcher", true);
return builder.UseMiddleware<DispatcherMiddleware>();
}
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Dispatcher
{
public class DispatcherEndpoint : Endpoint
{
public DispatcherEndpoint(string displayName)
{
DisplayName = displayName;
}
public override string DisplayName { get; }
}
}

View File

@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
namespace Microsoft.AspNetCore.Dispatcher
{
public class DispatcherEndpointStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
next(builder);
if (builder.Properties.ContainsKey("Dispatcher"))
{
builder.UseMiddleware<EndpointMiddleware>();
}
};
}
}
}

View File

@ -1,10 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Dispatcher;
using Microsoft.AspNetCore.Http;
namespace DispatcherSample
namespace Microsoft.AspNetCore.Dispatcher
{
public class DispatcherFeature : IDispatcherFeature
{

View File

@ -0,0 +1,60 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Dispatcher
{
public class DispatcherMiddleware
{
private readonly RequestDelegate _next;
public DispatcherMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var dictionary = new Dictionary<string, DispatcherFeature>
{
{
"/example",
new DispatcherFeature
{
Endpoint = new DispatcherEndpoint("example"),
RequestDelegate = async (context) =>
{
await context.Response.WriteAsync("Hello from the example!");
}
}
},
{
"/example2",
new DispatcherFeature
{
Endpoint = new DispatcherEndpoint("example2"),
RequestDelegate = async (context) =>
{
await context.Response.WriteAsync("Hello from the second example!");
}
}
},
};
if (dictionary.TryGetValue(httpContext.Request.Path, out var value))
{
var dispatcherFeature = new DispatcherFeature
{
Endpoint = value.Endpoint,
RequestDelegate = value.RequestDelegate
};
httpContext.Features.Set<IDispatcherFeature>(dispatcherFeature);
await _next(httpContext);
}
}
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Dispatcher;
using Microsoft.AspNetCore.Hosting;
namespace Microsoft.Extensions.DependencyInjection
{
public static class DispatcherServiceCollectionExtensions
{
public static IServiceCollection AddDispatcher(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.AddSingleton<IStartupFilter, DispatcherEndpointStartupFilter>();
return services;
}
}
}

View File

@ -0,0 +1,31 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Dispatcher
{
public class EndpointMiddleware
{
private RequestDelegate _next;
public EndpointMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var feature = context.Features.Get<IDispatcherFeature>();
if (feature.RequestDelegate == null)
{
await _next(context);
}
else
{
await feature.RequestDelegate(context);
}
}
}
}

View File

@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" />
</ItemGroup>