Implement Program.Main and ServerManager. Add Startup search.

This commit is contained in:
Chris Ross 2014-03-12 15:07:37 -07:00
parent 45adfac95b
commit a3eb280275
15 changed files with 281 additions and 63 deletions

View File

@ -0,0 +1,21 @@
using Microsoft.AspNet.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KWebStartup
{
public class Startup
{
public void Configuration(IBuilder app)
{
app.Run(async context =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hello world");
});
}
}
}

View File

@ -0,0 +1,32 @@
{
"version": "0.1-alpha-*",
"dependencies": {
"Microsoft.AspNet.Hosting": "0.1-alpha-*",
"Microsoft.AspNet.Server.WebListener": "0.1-alpha-*"
},
"commands": { "web": "Microsoft.AspNet.Hosting server.name=Microsoft.AspNet.Server.WebListener" },
"configurations": {
"net45": {
},
"k10": {
"dependencies": {
"System.Console": "4.0.0.0",
"System.Collections": "4.0.0.0",
"System.Diagnostics.Debug": "4.0.10.0",
"System.Diagnostics.Tools": "4.0.0.0",
"System.Globalization": "4.0.10.0",
"System.IO": "4.0.0.0",
"System.IO.FileSystem": "4.0.0.0",
"System.IO.FileSystem.Primitives": "4.0.0.0",
"System.Linq": "4.0.0.0",
"System.Reflection": "4.0.10.0",
"System.Resources.ResourceManager": "4.0.0.0",
"System.Runtime": "4.0.20.0",
"System.Runtime.Extensions": "4.0.10.0",
"System.Runtime.InteropServices": "4.0.10.0",
"System.Text.Encoding": "4.0.10.0",
"System.Threading.Tasks": "4.0.0.0"
}
}
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace Microsoft.Net.Runtime
{
[AssemblyNeutral]
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class AssemblyNeutralAttribute : Attribute
{
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Threading;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Hosting.Builder;
using Microsoft.AspNet.Hosting.Startup;
using Microsoft.AspNet.Hosting.Server;
@ -54,12 +55,13 @@ namespace Microsoft.AspNet.Hosting
private void EnsureServerFactory(HostingContext context)
{
context.ServerFactory = context.ServerFactory ?? context.Services.GetService<IServerFactory>();
if (context.ServerFactory != null)
{
return;
}
context.ServerFactory = _serverManager.GetServer(context.ServerName);
context.ServerFactory = _serverManager.GetServerFactory(context.ServerName);
}
private void EnsureApplicationDelegate(HostingContext context)

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Hosting
public static IEnumerable<IServiceDescriptor> GetDefaultServices(IConfiguration configuration)
{
yield return DescribeService<IHostingEngine, HostingEngine>(configuration);
yield return DescribeService<IServerFactoryProvider, ServerFactoryProvider>(configuration);
yield return DescribeService<IServerManager, ServerManager>(configuration);
yield return DescribeService<IStartupManager, StartupManager>(configuration);
yield return DescribeService<IStartupLoaderProvider, StartupLoaderProvider>(configuration);

View File

@ -0,0 +1,14 @@
using System;
using System.Runtime.Versioning;
namespace Microsoft.Net.Runtime
{
[AssemblyNeutral]
public interface IApplicationEnvironment
{
string ApplicationName { get; }
string Version { get; }
string ApplicationBasePath { get; }
FrameworkName TargetFramework { get; }
}
}

View File

@ -0,0 +1,60 @@
using Microsoft.AspNet.ConfigurationModel;
using Microsoft.AspNet.ConfigurationModel.Sources;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.Net.Runtime;
using System;
using System.IO;
namespace Microsoft.AspNet.Hosting
{
public class Program
{
private const string HostingIniFile = "Microsoft.AspNet.Hosting.ini";
private readonly IServiceProvider _serviceProvider;
public Program(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Main(string[] args)
{
var config = new Configuration();
config.AddCommandLine(args);
config.AddEnvironmentVariables();
if (File.Exists(HostingIniFile))
{
config.AddIniFile(HostingIniFile);
}
var services = new ServiceProvider(_serviceProvider)
.Add(HostingServices.GetDefaultServices(config));
var appEnvironment = _serviceProvider.GetService<IApplicationEnvironment>();
var context = new HostingContext()
{
Services = services,
ServerName = config.Get("server.name"), // TODO: Key names
ApplicationName = config.Get("app.name") // TODO: Key names
?? appEnvironment.ApplicationName,
};
var engine = services.GetService<IHostingEngine>();
if (engine == null)
{
throw new Exception("TODO: IHostingEngine service not available exception");
}
using (engine.Start(context))
{
#if NET45
Console.WriteLine("Started");
Console.ReadLine();
#endif
}
}
}
}

View File

@ -1,9 +1,11 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.Net.Runtime;
namespace Microsoft.AspNet.Hosting.Server
{
[AssemblyNeutral]
public interface IServerFactory
{
IDisposable Start(Func<object, Task> application);

View File

@ -1,7 +0,0 @@
namespace Microsoft.AspNet.Hosting.Server
{
public interface IServerFactoryProvider
{
IServerFactory GetServerFactory(string serverName);
}
}

View File

@ -2,6 +2,6 @@ namespace Microsoft.AspNet.Hosting.Server
{
public interface IServerManager
{
IServerFactory GetServer(string serverName);
IServerFactory GetServerFactory(string serverName);
}
}

View File

@ -1,12 +1,89 @@
using Microsoft.AspNet.DependencyInjection;
using System;
using System.Linq;
using System.Reflection;
namespace Microsoft.AspNet.Hosting.Server
{
public class ServerManager : IServerManager
{
public IServerFactory GetServer(string serverName)
private readonly IServiceProvider _services;
public ServerManager(IServiceProvider services)
{
throw new NotImplementedException();
_services = services;
}
public IServerFactory GetServerFactory(string serverFactoryIdentifier)
{
if (string.IsNullOrWhiteSpace(serverFactoryIdentifier))
{
throw new ArgumentNullException("serverFactoryIdentifier");
}
string typeName;
string assemblyName;
var parts = serverFactoryIdentifier.Split(new[] { ',' }, 2);
if (parts.Length == 1)
{
typeName = null;
assemblyName = serverFactoryIdentifier;
}
else if (parts.Length == 2)
{
typeName = parts[0];
assemblyName = parts[1];
}
else
{
throw new ArgumentException("TODO: Unrecognized format", "serverFactoryIdentifier");
}
var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null)
{
throw new Exception(String.Format("TODO: assembly {0} failed to load message", assemblyName));
}
Type type = null;
Type interfaceInfo;
if (string.IsNullOrWhiteSpace(typeName))
{
foreach (var typeInfo in assembly.DefinedTypes)
{
interfaceInfo = typeInfo.ImplementedInterfaces.FirstOrDefault(interf =>
interf.FullName == typeof(IServerFactory).FullName);
if (interfaceInfo != null)
{
type = typeInfo.AsType();
}
}
if (type == null)
{
throw new Exception(String.Format("TODO: type {0} failed to load message", typeName ?? "<null>"));
}
}
else
{
type = assembly.GetType(typeName) ?? assembly.GetType(assemblyName + "." + typeName);
if (type == null)
{
throw new Exception(String.Format("TODO: type {0} failed to load message", typeName ?? "<null>"));
}
interfaceInfo = type.GetTypeInfo().ImplementedInterfaces.FirstOrDefault(interf =>
interf.FullName == typeof(IServerFactory).FullName);
if (interfaceInfo == null)
{
throw new Exception("TODO: IServerFactory interface not found");
}
}
object instance = ActivatorUtilities.GetServiceOrCreateInstance(_services, type);
return (IServerFactory)instance;
}
}
}

View File

@ -1,13 +0,0 @@
using System;
using Microsoft.AspNet.Hosting.Server;
namespace Microsoft.AspNet.Hosting
{
public class ServerFactoryProvider : IServerFactoryProvider
{
public IServerFactory GetServerFactory(string serverFactoryIdentifier)
{
throw new NotImplementedException();
}
}
}

View File

@ -25,38 +25,61 @@ namespace Microsoft.AspNet.Hosting.Startup
return _next.LoadStartup(applicationName, diagnosticMessages);
}
string typeName;
string assemblyName;
var parts = applicationName.Split(new[] { ',' }, 2);
if (parts.Length == 2)
if (parts.Length == 1)
{
var typeName = parts[0];
var assemblyName = parts[1];
var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null)
{
throw new Exception(String.Format("TODO: assembly {0} failed to load message", assemblyName));
}
var type = assembly.GetType(typeName) ?? assembly.GetType(assemblyName + "." + typeName);
if (type == null)
{
throw new Exception(String.Format("TODO: type {0} failed to load message", typeName));
}
var methodInfo = type.GetTypeInfo().GetDeclaredMethod("Configuration");
if (methodInfo == null)
{
throw new Exception("TODO: Configuration method not found");
}
object instance = null;
if (!methodInfo.IsStatic)
{
instance = ActivatorUtilities.GetServiceOrCreateInstance(_services, type);
}
return builder => methodInfo.Invoke(instance, new object[] { builder });
typeName = null;
assemblyName = applicationName;
}
throw new Exception("TODO: Unrecognized format");
else if (parts.Length == 2)
{
typeName = parts[0];
assemblyName = parts[1];
}
else
{
throw new Exception("TODO: Unrecognized format");
}
var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null)
{
throw new Exception(String.Format("TODO: assembly {0} failed to load message", assemblyName));
}
Type type = null;
if (string.IsNullOrWhiteSpace(typeName))
{
var typeInfo = assembly.DefinedTypes.FirstOrDefault(aType => aType.Name.Equals("Startup"));
if (typeInfo != null)
{
type = typeInfo.AsType();
}
}
else
{
type = assembly.GetType(typeName);
}
if (type == null)
{
throw new Exception(String.Format("TODO: type {0} failed to load message", typeName));
}
var methodInfo = type.GetTypeInfo().GetDeclaredMethod("Configuration");
if (methodInfo == null)
{
throw new Exception("TODO: Configuration method not found");
}
object instance = null;
if (!methodInfo.IsStatic)
{
instance = ActivatorUtilities.GetServiceOrCreateInstance(_services, type);
}
return builder => methodInfo.Invoke(instance, new object[] { builder });
}
}
}

View File

@ -14,6 +14,9 @@
"System.Collections": "4.0.0.0",
"System.ComponentModel": "4.0.0.0",
"System.Diagnostics.Debug": "4.0.10.0",
"System.IO": "4.0.0.0",
"System.IO.FileSystem": "4.0.0.0",
"System.IO.FileSystem.Primitives": "4.0.0.0",
"System.Linq": "4.0.0.0",
"System.Reflection": "4.0.10.0",
"System.Runtime": "4.0.20.0",

View File

@ -10,7 +10,7 @@ using Xunit;
namespace Microsoft.AspNet.Hosting.Tests
{
public class HostingEngineTests : IServerManager, IServerFactory
public class HostingEngineTests : IServerFactory
{
private readonly IList<StartInstance> _startInstances = new List<StartInstance>();
@ -29,14 +29,13 @@ namespace Microsoft.AspNet.Hosting.Tests
public void HostingEngineCanBeStarted()
{
var services = new ServiceProvider()
.Add(HostingServices.GetDefaultServices()
.Where(descriptor => descriptor.ServiceType != typeof(IServerManager)))
.AddInstance<IServerManager>(this);
.Add(HostingServices.GetDefaultServices());
var engine = services.GetService<IHostingEngine>();
var context = new HostingContext
{
ServerFactory = this,
ApplicationName = "Microsoft.AspNet.Hosting.Tests.Fakes.FakeStartup, Microsoft.AspNet.Hosting.Tests"
};
@ -51,11 +50,6 @@ namespace Microsoft.AspNet.Hosting.Tests
Assert.Equal(1, _startInstances[0].DisposeCalls);
}
public IServerFactory GetServer(string serverName)
{
return this;
}
public void Initialize(IBuilder builder)
{