Praburaj 2015-02-25 16:05:22 -08:00
parent d687ec2c26
commit 00864c1af4
17 changed files with 62 additions and 182 deletions

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Hosting
/// <summary>
/// Signals the ApplicationStopping event and blocks until it completes.
/// </summary>
public void SignalStopping()
public void NotifyStopping()
{
try
{
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Hosting
/// <summary>
/// Signals the ApplicationStopped event and blocks until it completes.
/// </summary>
public void SignalStopped()
public void NotifyStopped()
{
try
{

View File

@ -3,7 +3,6 @@
using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.Framework.ConfigurationModel;
@ -11,7 +10,7 @@ namespace Microsoft.AspNet.Hosting
{
public class HostingContext
{
public IServiceProvider Services { get; set; }
public IApplicationLifetime ApplicationLifeTime { get; set; }
public IConfiguration Configuration { get; set; }
public IApplicationBuilder Builder { get; set; }
@ -21,7 +20,7 @@ namespace Microsoft.AspNet.Hosting
public Action<IApplicationBuilder> ApplicationStartup { get; set; }
public RequestDelegate ApplicationDelegate { get; set; }
public string ServerName { get; set; }
public string ServerFactoryAssembly { get; set; }
public IServerFactory ServerFactory { get; set; }
public IServerInformation Server { get; set; }
}

View File

@ -2,31 +2,32 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.AspNet.Hosting.Builder;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Hosting.Startup;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Hosting
{
public class HostingEngine : IHostingEngine
{
private readonly IServerManager _serverManager;
private readonly IStartupManager _startupManager;
private readonly IServerLoader _serverManager;
private readonly IStartupLoader _startupLoader;
private readonly IApplicationBuilderFactory _builderFactory;
private readonly IHttpContextFactory _httpContextFactory;
private readonly IHttpContextAccessor _contextAccessor;
public HostingEngine(
IServerManager serverManager,
IStartupManager startupManager,
IServerLoader serverManager,
IStartupLoader startupLoader,
IApplicationBuilderFactory builderFactory,
IHttpContextFactory httpContextFactory,
IHttpContextAccessor contextAccessor)
{
_serverManager = serverManager;
_startupManager = startupManager;
_startupLoader = startupLoader;
_builderFactory = builderFactory;
_httpContextFactory = httpContextFactory;
_contextAccessor = contextAccessor;
@ -39,16 +40,16 @@ namespace Microsoft.AspNet.Hosting
InitalizeServerFactory(context);
EnsureApplicationDelegate(context);
var applicationLifetime = (ApplicationLifetime)context.Services.GetRequiredService<IApplicationLifetime>();
var applicationLifetime = (ApplicationLifetime)context.ApplicationLifeTime;
var pipeline = new PipelineInstance(_httpContextFactory, context.ApplicationDelegate, _contextAccessor);
var server = context.ServerFactory.Start(context.Server, pipeline.Invoke);
return new Disposable(() =>
{
applicationLifetime.SignalStopping();
applicationLifetime.NotifyStopping();
server.Dispose();
pipeline.Dispose();
applicationLifetime.SignalStopped();
applicationLifetime.NotifyStopped();
});
}
@ -69,7 +70,7 @@ namespace Microsoft.AspNet.Hosting
return;
}
context.ServerFactory = _serverManager.GetServerFactory(context.ServerName);
context.ServerFactory = _serverManager.LoadServerFactory(context.ServerFactoryAssembly);
}
private void InitalizeServerFactory(HostingContext context)
@ -105,9 +106,16 @@ namespace Microsoft.AspNet.Hosting
return;
}
context.ApplicationStartup = _startupManager.LoadStartup(
var diagnosticMessages = new List<string>();
context.ApplicationStartup = _startupLoader.LoadStartup(
context.ApplicationName,
context.EnvironmentName);
context.EnvironmentName,
diagnosticMessages);
if (context.ApplicationStartup == null)
{
throw new Exception(diagnosticMessages.Aggregate("TODO: web application entrypoint not found message", (a, b) => a + "\r\n" + b));
}
}
private class Disposable : IDisposable

View File

@ -26,10 +26,9 @@ namespace Microsoft.Framework.DependencyInjection
var describer = new ServiceDescriber(configuration);
services.TryAdd(describer.Transient<IHostingEngine, HostingEngine>());
services.TryAdd(describer.Transient<IServerManager, ServerManager>());
services.TryAdd(describer.Transient<IServerLoader, ServerLoader>());
services.TryAdd(describer.Transient<IStartupManager, StartupManager>());
services.TryAdd(describer.Transient<IStartupLoaderProvider, StartupLoaderProvider>());
services.TryAdd(describer.Transient<IStartupLoader, StartupLoader>());
services.TryAdd(describer.Transient<IApplicationBuilderFactory, ApplicationBuilderFactory>());
services.TryAdd(describer.Transient<IHttpContextFactory, HttpContextFactory>());

View File

@ -24,8 +24,6 @@ namespace Microsoft.AspNet.Hosting
_serviceProvider = serviceProvider;
}
public void Main(string[] args)
{
var config = new Configuration();
@ -41,12 +39,13 @@ namespace Microsoft.AspNet.Hosting
var appEnv = services.GetRequiredService<IApplicationEnvironment>();
var hostingEnv = services.GetRequiredService<IHostingEnvironment>();
var applicationLifeTime = services.GetRequiredService<IApplicationLifetime>();
var context = new HostingContext()
{
Services = services,
ApplicationLifeTime = applicationLifeTime,
Configuration = config,
ServerName = config.Get("server"), // TODO: Key names
ServerFactoryAssembly = config.Get("server"), // TODO: Key names
ApplicationName = config.Get("app") // TODO: Key names
?? appEnv.ApplicationName,
EnvironmentName = hostingEnv.EnvironmentName,

View File

@ -3,8 +3,8 @@
namespace Microsoft.AspNet.Hosting.Server
{
public interface IServerManager
public interface IServerLoader
{
IServerFactory GetServerFactory(string serverName);
IServerFactory LoadServerFactory(string serverName);
}
}

View File

@ -8,16 +8,16 @@ using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Hosting.Server
{
public class ServerManager : IServerManager
public class ServerLoader : IServerLoader
{
private readonly IServiceProvider _services;
public ServerManager(IServiceProvider services)
public ServerLoader(IServiceProvider services)
{
_services = services;
}
public IServerFactory GetServerFactory(string serverFactoryIdentifier)
public IServerFactory LoadServerFactory(string serverFactoryIdentifier)
{
if (string.IsNullOrEmpty(serverFactoryIdentifier))
{

View File

@ -1,12 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Hosting.Startup
{
public interface IStartupLoaderProvider
{
int Order { get; }
IStartupLoader CreateStartupLoader(IStartupLoader next);
}
}

View File

@ -1,16 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Hosting.Startup
{
public interface IStartupManager
{
Action<IApplicationBuilder> LoadStartup(
string applicationName,
string environmentName);
}
}

View File

@ -1,28 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Hosting.Startup
{
public class NullStartupLoader : IStartupLoader
{
static NullStartupLoader()
{
Instance = new NullStartupLoader();
}
public static IStartupLoader Instance { get; private set; }
public Action<IApplicationBuilder> LoadStartup(
string applicationName,
string environmentName,
IList<string> diagnosticMessages)
{
return null;
}
}
}

View File

@ -15,14 +15,10 @@ namespace Microsoft.AspNet.Hosting.Startup
public class StartupLoader : IStartupLoader
{
private readonly IServiceProvider _services;
private readonly IStartupLoader _next;
public StartupLoader(
IServiceProvider services,
IStartupLoader next)
public StartupLoader(IServiceProvider services)
{
_services = services;
_next = next;
}
private MethodInfo FindMethod(Type startupType, string methodName, string environmentName, Type returnType = null, bool required = true)
@ -94,9 +90,9 @@ namespace Microsoft.AspNet.Hosting.Startup
string environmentName,
IList<string> diagnosticMessages)
{
if (String.IsNullOrEmpty(applicationName))
if (string.IsNullOrEmpty(applicationName))
{
return _next.LoadStartup(applicationName, environmentName, diagnosticMessages);
throw new ArgumentNullException("applicationName");
}
var assembly = Assembly.Load(new AssemblyName(applicationName));
@ -156,7 +152,7 @@ namespace Microsoft.AspNet.Hosting.Startup
{
// IServiceProvider ConfigureServices(IServiceCollection)
builder.ApplicationServices = (Invoke(servicesMethod, instance, builder, services) as IServiceProvider)
?? builder.ApplicationServices;
?? builder.ApplicationServices;
}
else
{

View File

@ -1,24 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.Hosting.Startup
{
public class StartupLoaderProvider : IStartupLoaderProvider
{
private readonly IServiceProvider _services;
public StartupLoaderProvider(IServiceProvider services)
{
_services = services;
}
public int Order { get { return -100; } }
public IStartupLoader CreateStartupLoader(IStartupLoader next)
{
return new StartupLoader(_services, next);
}
}
}

View File

@ -1,42 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Hosting.Startup
{
public class StartupManager : IStartupManager
{
private readonly IEnumerable<IStartupLoaderProvider> _providers;
public StartupManager(IEnumerable<IStartupLoaderProvider> providers)
{
_providers = providers;
}
public Action<IApplicationBuilder> LoadStartup(
string applicationName,
string environmentName)
{
// build ordered chain of application loaders
var chain = _providers
.OrderBy(provider => provider.Order)
.Aggregate(NullStartupLoader.Instance, (next, provider) => provider.CreateStartupLoader(next));
// invoke chain to acquire application entrypoint and diagnostic messages
var diagnosticMessages = new List<string>();
var application = chain.LoadStartup(applicationName, environmentName, diagnosticMessages);
if (application == null)
{
throw new Exception(diagnosticMessages.Aggregate("TODO: web application entrypoint not found message", (a, b) => a + "\r\n" + b));
}
return application;
}
}
}

View File

@ -2,10 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
@ -31,13 +28,14 @@ namespace Microsoft.AspNet.TestHost
public TestServer(IConfiguration config, IServiceProvider serviceProvider, Action<IApplicationBuilder> appStartup)
{
var appEnv = serviceProvider.GetRequiredService<IApplicationEnvironment>();
var applicationLifeTime = serviceProvider.GetRequiredService<IApplicationLifetime>();
HostingContext hostContext = new HostingContext()
{
ApplicationName = appEnv.ApplicationName,
ApplicationLifeTime = applicationLifeTime,
Configuration = config,
ServerFactory = this,
Services = serviceProvider,
ApplicationStartup = appStartup
};

View File

@ -34,11 +34,12 @@ namespace Microsoft.AspNet.Hosting
var services = HostingServices.Create().BuildServiceProvider();
var engine = services.GetRequiredService<IHostingEngine>();
var applicationLifeTime = services.GetRequiredService<IApplicationLifetime>();
var context = new HostingContext
{
ApplicationLifeTime = applicationLifeTime,
ServerFactory = this,
Services = services,
ApplicationName = "Microsoft.AspNet.Hosting.Tests"
};

View File

@ -25,9 +25,10 @@ namespace Microsoft.AspNet.Hosting.Tests
serviceCollection.AddInstance<IFakeStartupCallback>(this);
var services = serviceCollection.BuildServiceProvider();
var manager = services.GetRequiredService<IStartupManager>();
var loader = services.GetRequiredService<IStartupLoader>();
var startup = manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", "WithServices");
var diagnosticMessages = new List<string>();
var startup = loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", "WithServices", diagnosticMessages);
startup.Invoke(new ApplicationBuilder(services));
@ -45,9 +46,10 @@ namespace Microsoft.AspNet.Hosting.Tests
public void StartupClassAddsConfigureServicesToApplicationServices(string environment)
{
var services = HostingServices.Create().BuildServiceProvider();
var manager = services.GetRequiredService<IStartupManager>();
var loader = services.GetRequiredService<IStartupLoader>();
var diagnosticMesssages = new List<string>();
var startup = manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", environment ?? "");
var startup = loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", environment ?? "", diagnosticMesssages);
var app = new ApplicationBuilder(services);
@ -65,9 +67,10 @@ namespace Microsoft.AspNet.Hosting.Tests
public void StartupClassConfigureServicesThatFallsbackToApplicationServices(string env)
{
var services = HostingServices.Create().BuildServiceProvider();
var manager = services.GetRequiredService<IStartupManager>();
var loader = services.GetRequiredService<IStartupLoader>();
var diagnosticMessages = new List<string>();
var startup = manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", env);
var startup = loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", env, diagnosticMessages);
var app = new ApplicationBuilder(services);
@ -82,9 +85,10 @@ namespace Microsoft.AspNet.Hosting.Tests
public void StartupClassWithConfigureServicesAndUseServicesHidesConfigureServices()
{
var services = HostingServices.Create().BuildServiceProvider();
var manager = services.GetRequiredService<IStartupManager>();
var loader = services.GetRequiredService<IStartupLoader>();
var diagnosticMessages = new List<string>();
var startup = manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", "UseServices");
var startup = loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", "UseServices", diagnosticMessages);
var app = new ApplicationBuilder(services);
@ -105,9 +109,10 @@ namespace Microsoft.AspNet.Hosting.Tests
var serviceCollection = HostingServices.Create();
serviceCollection.AddInstance<IFakeStartupCallback>(this);
var services = serviceCollection.BuildServiceProvider();
var manager = services.GetRequiredService<IStartupManager>();
var loader = services.GetRequiredService<IStartupLoader>();
var diagnosticMessages = new List<string>();
var ex = Assert.Throws<Exception>(() => manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", "Boom"));
var ex = Assert.Throws<Exception>(() => loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", "Boom", diagnosticMessages));
Assert.True(ex.Message.Contains("ConfigureBoom or Configure method not found"));
}
@ -116,11 +121,12 @@ namespace Microsoft.AspNet.Hosting.Tests
{
var serviceCollection = HostingServices.Create();
var services = serviceCollection.BuildServiceProvider();
var manager = services.GetRequiredService<IStartupManager>();
var loader = services.GetRequiredService<IStartupLoader>();
var app = new ApplicationBuilder(services);
var startup = manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", "WithConfigureServices");
var diagnosticMessages = new List<string>();
var startup = loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", "WithConfigureServices", diagnosticMessages);
startup.Invoke(app);

View File

@ -5,7 +5,6 @@ using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting.Builder;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Hosting.Startup;
using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.RequestContainer;
using Microsoft.Framework.DependencyInjection;
@ -83,11 +82,8 @@ namespace Microsoft.AspNet.Hosting.Tests
[Theory]
[InlineData(typeof(IHostingEngine))]
[InlineData(typeof(IServerManager))]
[InlineData(typeof(IStartupManager))]
[InlineData(typeof(IStartupLoaderProvider))]
[InlineData(typeof(IServerLoader))]
[InlineData(typeof(IApplicationBuilderFactory))]
[InlineData(typeof(IStartupLoaderProvider))]
[InlineData(typeof(IHttpContextFactory))]
[InlineData(typeof(ITypeActivator))]
[InlineData(typeof(IApplicationLifetime))]