GetDefaultServices -> AddHosting

Also stop adding options
This commit is contained in:
Hao Kung 2014-11-24 17:33:11 -08:00
parent aebfecdf87
commit a9827a4310
7 changed files with 67 additions and 99 deletions

View File

@ -4,14 +4,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Hosting.Builder;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Hosting.Startup;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.ServiceLookup;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.Runtime.Infrastructure;
namespace Microsoft.AspNet.Hosting
@ -24,7 +20,6 @@ namespace Microsoft.AspNet.Hosting
var manifest = fallbackProvider.GetRequiredService<IServiceManifest>();
foreach (var service in manifest.Services)
{
// REVIEW: should this be Singleton instead?
services.AddTransient(service, sp => fallbackProvider.GetService(service));
}
return services;
@ -39,45 +34,12 @@ namespace Microsoft.AspNet.Hosting
{
configuration = configuration ?? new Configuration();
var services = Import(fallbackServices);
services.Add(GetDefaultServices(configuration));
services.AddHosting(configuration);
services.AddSingleton<IServiceManifest>(sp => new HostingManifest(fallbackServices));
services.AddInstance<IConfigureHostingEnvironment>(new ConfigureHostingEnvironment(configuration));
return services;
}
// REVIEW: make this private?
public static IEnumerable<IServiceDescriptor> GetDefaultServices(IConfiguration configuration = null)
{
configuration = configuration ?? new Configuration();
var describer = new ServiceDescriber(configuration);
yield return describer.Transient<IHostingEngine, HostingEngine>();
yield return describer.Transient<IServerManager, ServerManager>();
yield return describer.Transient<IStartupManager, StartupManager>();
yield return describer.Transient<IStartupLoaderProvider, StartupLoaderProvider>();
yield return describer.Transient<IApplicationBuilderFactory, ApplicationBuilderFactory>();
yield return describer.Transient<IHttpContextFactory, HttpContextFactory>();
yield return describer.Instance<IApplicationLifetime>(new ApplicationLifetime());
// These three services as exported in the manifest
yield return describer.Singleton<ITypeActivator, TypeActivator>();
yield return describer.Singleton<IHostingEnvironment, HostingEnvironment>();
// TODO: Do we expect this to be provide by the runtime eventually?
yield return describer.Singleton<ILoggerFactory, LoggerFactory>();
// TODO: Remove the below services and push the responsibility to frameworks to add
yield return describer.Scoped(typeof(IContextAccessor<>), typeof(ContextAccessor<>));
foreach (var service in OptionsServices.GetDefaultServices())
{
yield return service;
}
}
// Manifest exposes the fallback manifest in addition to ITypeActivator, IHostingEnvironment, and ILoggerFactory
private class HostingManifest : IServiceManifest
{
public HostingManifest(IServiceProvider fallback)

View File

@ -0,0 +1,53 @@
// 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 Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Builder;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Hosting.Startup;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.Logging;
namespace Microsoft.Framework.DependencyInjection
{
public static class HostingServicesExtensions
{
// REVIEW: Logging doesn't depend on DI, where should this live?
public static IServiceCollection AddLogging(this IServiceCollection services, IConfiguration config = null)
{
var describe = new ServiceDescriber(config);
services.TryAdd(describe.Singleton<ILoggerFactory, LoggerFactory>());
return services;
}
public static IServiceCollection AddHosting(this IServiceCollection services, IConfiguration configuration = null)
{
var describer = new ServiceDescriber(configuration);
services.TryAdd(describer.Transient<IHostingEngine, HostingEngine>());
services.TryAdd(describer.Transient<IServerManager, ServerManager>());
services.TryAdd(describer.Transient<IStartupManager, StartupManager>());
services.TryAdd(describer.Transient<IStartupLoaderProvider, StartupLoaderProvider>());
services.TryAdd(describer.Transient<IApplicationBuilderFactory, ApplicationBuilderFactory>());
services.TryAdd(describer.Transient<IHttpContextFactory, HttpContextFactory>());
services.TryAdd(describer.Instance<IApplicationLifetime>(new ApplicationLifetime()));
services.AddTypeActivator(configuration);
// TODO: Do we expect this to be provide by the runtime eventually?
services.AddLogging(configuration);
// REVIEW: okay to use existing hosting environment/httpcontext if specified?
services.TryAdd(describer.Singleton<IHostingEnvironment, HostingEnvironment>());
// TODO: Remove this once we have IHttpContextAccessor
services.AddContextAccessor(configuration);
// REVIEW: don't try add because we pull out IEnumerable<IConfigureHostingEnvironment>?
services.AddInstance<IConfigureHostingEnvironment>(new ConfigureHostingEnvironment(configuration));
return services;
}
}
}

View File

@ -152,10 +152,8 @@ namespace Microsoft.AspNet.Hosting.Startup
if (servicesMethod != null)
{
var services = HostingServices.Create(builder.ApplicationServices);
// TODO: remove adding options
services.Add(OptionsServices.GetDefaultServices());
services.AddScoped(typeof(IContextAccessor<>), typeof(ContextAccessor<>));
// TODO: remove this once IHttpContextAccessor service is added
services.AddContextAccessor();
if (servicesMethod.ReturnType == typeof(IServiceProvider))
{
// IServiceProvider ConfigureServices(IServiceCollection)

View File

@ -7,7 +7,6 @@ using Microsoft.AspNet.RequestContainer;
using Microsoft.AspNet.Hosting;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Builder
{
@ -49,9 +48,8 @@ namespace Microsoft.AspNet.Builder
// Import services from hosting/KRE as fallback
var serviceCollection = HostingServices.Create(builder.ApplicationServices);
// TODO: should remove OptionServices here soon...
serviceCollection.Add(OptionsServices.GetDefaultServices());
serviceCollection.AddScoped(typeof(IContextAccessor<>), typeof(ContextAccessor<>));
// TODO: remove this once IHttpContextAccessor service is added
serviceCollection.AddContextAccessor();
// REVIEW: serviceCollection has the merged services, manifests are lost after this
builder.ApplicationServices = configureServices(serviceCollection);

View File

@ -17,11 +17,13 @@ namespace Microsoft.AspNet.Hosting.Fakes
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o => o.Configured = true);
}
public void ConfigureDevServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
@ -31,6 +33,7 @@ namespace Microsoft.AspNet.Hosting.Fakes
public void ConfigureRetailServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
@ -40,6 +43,7 @@ namespace Microsoft.AspNet.Hosting.Fakes
public static void ConfigureStaticServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
@ -49,8 +53,7 @@ namespace Microsoft.AspNet.Hosting.Fakes
public static IServiceProvider ConfigureStaticProviderServices()
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
var services = new ServiceCollection().AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
@ -71,6 +74,7 @@ namespace Microsoft.AspNet.Hosting.Fakes
public IServiceProvider ConfigureProviderServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
@ -81,8 +85,7 @@ namespace Microsoft.AspNet.Hosting.Fakes
public IServiceProvider ConfigureProviderArgsServices(IApplicationBuilder me)
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
var services = new ServiceCollection().AddOptions();
services.Configure<FakeOptions>(o =>
{
o.Configured = true;

View File

@ -21,8 +21,7 @@ namespace Microsoft.AspNet.Hosting.Tests
[Fact]
public void StartupClassMayHaveHostingServicesInjected()
{
var serviceCollection = new ServiceCollection();
serviceCollection.Add(HostingServices.GetDefaultServices());
var serviceCollection = new ServiceCollection().AddHosting();
serviceCollection.AddInstance<IFakeStartupCallback>(this);
var services = serviceCollection.BuildServiceProvider();

View File

@ -1,45 +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.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.Runtime.Infrastructure;
using Xunit;
namespace Microsoft.AspNet.Hosting.Tests
{
public class UseServicesFacts
{
[Fact]
public void OptionsAccessorCanBeResolvedAfterCallingUseServicesWithAction()
{
var builder = new ApplicationBuilder(CallContextServiceLocator.Locator.ServiceProvider);
builder.UseServices(serviceCollection => { });
var optionsAccessor = builder.ApplicationServices.GetRequiredService<IOptions<object>>();
Assert.NotNull(optionsAccessor);
}
[Fact]
public void OptionsAccessorCanBeResolvedAfterCallingUseServicesWithFunc()
{
var builder = new ApplicationBuilder(CallContextServiceLocator.Locator.ServiceProvider);
IServiceProvider serviceProvider = null;
builder.UseServices(serviceCollection =>
{
serviceProvider = serviceCollection.BuildServiceProvider();
return serviceProvider;
});
Assert.Same(serviceProvider, builder.ApplicationServices);
var optionsAccessor = builder.ApplicationServices.GetRequiredService<IOptions<object>>();
Assert.NotNull(optionsAccessor);
}
}
}