React to fallback changes

This commit is contained in:
Hao Kung 2014-11-20 17:43:55 -08:00
parent 90098411c6
commit d9893b260a
8 changed files with 106 additions and 23 deletions

View File

@ -61,8 +61,7 @@ namespace MvcSample.Web
// Create the container and use the default application services as a fallback // Create the container and use the default application services as a fallback
AutofacRegistration.Populate( AutofacRegistration.Populate(
builder, builder,
services, services);
fallbackServiceProvider: app.ApplicationServices);
builder.RegisterModule<MonitoringModule>(); builder.RegisterModule<MonitoringModule>();

View File

@ -3,6 +3,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Mvc.Razor; using Microsoft.AspNet.Mvc.Razor;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
@ -26,22 +29,50 @@ namespace Microsoft.AspNet.Mvc
public virtual void BeforeCompile(IBeforeCompileContext context) public virtual void BeforeCompile(IBeforeCompileContext context)
{ {
var sc = new ServiceCollection();
var appEnv = _appServices.GetRequiredService<IApplicationEnvironment>(); var appEnv = _appServices.GetRequiredService<IApplicationEnvironment>();
var setup = new RazorViewEngineOptionsSetup(appEnv); var setup = new RazorViewEngineOptionsSetup(appEnv);
var accessor = new OptionsManager<RazorViewEngineOptions>(new[] { setup }); var accessor = new OptionsManager<RazorViewEngineOptions>(new[] { setup });
var sc = new ServiceCollection();
sc.AddInstance<IOptions<RazorViewEngineOptions>>(accessor); sc.AddInstance<IOptions<RazorViewEngineOptions>>(accessor);
sc.Add(MvcServices.GetDefaultServices()); sc.Add(MvcServices.GetDefaultServices());
var sp = sc.BuildServiceProvider(_appServices);
var viewCompiler = new RazorPreCompiler(sp); var viewCompiler = new RazorPreCompiler(BuildFallbackServiceProvider(sc, _appServices));
viewCompiler.CompileViews(context); viewCompiler.CompileViews(context);
} }
public void AfterCompile(IAfterCompileContext context) public void AfterCompile(IAfterCompileContext context)
{ {
} }
// TODO: KILL THIS
private static IServiceProvider BuildFallbackServiceProvider(IEnumerable<IServiceDescriptor> services, IServiceProvider fallback)
{
var sc = HostingServices.Create(fallback);
sc.Add(services);
// Build the manifest
var manifestTypes = services.Where(t => t.ServiceType.GetTypeInfo().GenericTypeParameters.Length == 0
&& t.ServiceType != typeof(IServiceManifest)
&& t.ServiceType != typeof(IServiceProvider))
.Select(t => t.ServiceType).Distinct();
sc.AddInstance<IServiceManifest>(new ServiceManifest(manifestTypes, fallback.GetRequiredService<IServiceManifest>()));
return sc.BuildServiceProvider();
}
private class ServiceManifest : IServiceManifest
{
public ServiceManifest(IEnumerable<Type> services, IServiceManifest fallback = null)
{
Services = services;
if (fallback != null)
{
Services = Services.Concat(fallback.Services).Distinct();
}
}
public IEnumerable<Type> Services { get; private set; }
}
} }
} }

View File

@ -110,7 +110,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
{ {
var services = new ServiceCollection(); var services = new ServiceCollection();
services.AddInstance(waitService); services.AddInstance(waitService);
return services.BuildServiceProvider(_provider); return TestHelper.CreateServices("RazorWebSite", services);
} }
private string GetTrimmedString(Stream stream) private string GetTrimmedString(Stream stream)

View File

@ -8,7 +8,6 @@ using InlineConstraints;
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost; using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Mvc.FunctionalTests namespace Microsoft.AspNet.Mvc.FunctionalTests
@ -20,10 +19,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
public InlineConstraintTests() public InlineConstraintTests()
{ {
_provider = TestHelper.CreateServices("InlineConstraintsWebSite"); var services = new ServiceCollection()
_provider = new ServiceCollection() .AddScoped<ICommandLineArgumentBuilder, DefaultCommandLineArgumentBuilder>();
.AddScoped<ICommandLineArgumentBuilder, DefaultCommandLineArgumentBuilder>() _provider = TestHelper.CreateServices("InlineConstraintsWebSite", services);
.BuildServiceProvider(_provider);
} }
[Fact] [Fact]

View File

@ -7,7 +7,6 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost; using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using RazorInstrumentationWebSite; using RazorInstrumentationWebSite;
using Xunit; using Xunit;
@ -209,7 +208,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
{ {
var services = new ServiceCollection(); var services = new ServiceCollection();
services.AddInstance(pageExecutionContext); services.AddInstance(pageExecutionContext);
return services.BuildServiceProvider(_services); return TestHelper.CreateServices("RazorInstrumentationWebsite", services);
} }
} }
} }

View File

@ -2,10 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.AspNet.Hosting;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback; using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.DependencyInjection.ServiceLookup;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
using Microsoft.Framework.Runtime; using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure; using Microsoft.Framework.Runtime.Infrastructure;
@ -17,12 +21,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Path from Mvc\\test\\Microsoft.AspNet.Mvc.FunctionalTests // Path from Mvc\\test\\Microsoft.AspNet.Mvc.FunctionalTests
private static readonly string WebsitesDirectoryPath = Path.Combine("..", "WebSites"); private static readonly string WebsitesDirectoryPath = Path.Combine("..", "WebSites");
public static IServiceProvider CreateServices(string applicationWebSiteName) public static IServiceProvider CreateServices(string applicationWebSiteName, IServiceCollection newServices = null)
{ {
return CreateServices(applicationWebSiteName, WebsitesDirectoryPath); return CreateServices(applicationWebSiteName, WebsitesDirectoryPath, newServices);
} }
public static IServiceProvider CreateServices(string applicationWebSiteName, string applicationPath) public static IServiceProvider CreateServices(string applicationWebSiteName, string applicationPath, IServiceCollection newServices = null)
{ {
var originalProvider = CallContextServiceLocator.Locator.ServiceProvider; var originalProvider = CallContextServiceLocator.Locator.ServiceProvider;
var appEnvironment = originalProvider.GetRequiredService<IApplicationEnvironment>(); var appEnvironment = originalProvider.GetRequiredService<IApplicationEnvironment>();
@ -34,7 +38,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// To compensate for this, we need to calculate the original path and override the application // To compensate for this, we need to calculate the original path and override the application
// environment value so that components like the view engine work properly in the context of the // environment value so that components like the view engine work properly in the context of the
// test. // test.
var appBasePath = CalculateApplicationBasePath(appEnvironment, applicationWebSiteName, applicationPath); var appBasePath = CalculateApplicationBasePath(appEnvironment, applicationWebSiteName, applicationPath);
var services = new ServiceCollection(); var services = new ServiceCollection();
services.AddInstance( services.AddInstance(
@ -58,7 +62,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
typeof(ILoggerFactory), typeof(ILoggerFactory),
NullLoggerFactory.Instance); NullLoggerFactory.Instance);
return services.BuildServiceProvider(originalProvider); if (newServices != null)
{
services.Add(newServices);
}
return BuildFallbackServiceProvider(services, originalProvider);
} }
// Calculate the path relative to the application base path. // Calculate the path relative to the application base path.
@ -106,5 +115,34 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
CallContextServiceLocator.Locator.ServiceProvider = _originalProvider; CallContextServiceLocator.Locator.ServiceProvider = _originalProvider;
} }
} }
// TODO: Kill this code
private static IServiceProvider BuildFallbackServiceProvider(IEnumerable<IServiceDescriptor> services, IServiceProvider fallback)
{
var sc = HostingServices.Create(fallback);
sc.Add(services);
// Build the manifest
var manifestTypes = services.Where(t => t.ServiceType.GetTypeInfo().GenericTypeParameters.Length == 0
&& t.ServiceType != typeof(IServiceManifest)
&& t.ServiceType != typeof(IServiceProvider))
.Select(t => t.ServiceType).Distinct();
sc.AddInstance<IServiceManifest>(new ServiceManifest(manifestTypes, fallback.GetRequiredService<IServiceManifest>()));
return sc.BuildServiceProvider();
}
private class ServiceManifest : IServiceManifest
{
public ServiceManifest(IEnumerable<Type> services, IServiceManifest fallback = null)
{
Services = services;
if (fallback != null)
{
Services = Services.Concat(fallback.Services).Distinct();
}
}
public IEnumerable<Type> Services { get; private set; }
}
} }
} }

View File

@ -18,9 +18,8 @@ namespace AutofacWebSite
services.AddTransient<HelloWorldBuilder>(); services.AddTransient<HelloWorldBuilder>();
var builder = new ContainerBuilder(); var builder = new ContainerBuilder();
AutofacRegistration.Populate(builder, AutofacRegistration.Populate(builder,
services, services);
fallbackServiceProvider: app.ApplicationServices);
var container = builder.Build(); var container = builder.Build();

View File

@ -5,6 +5,7 @@ using System;
using System.IO; using System.IO;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Hosting;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback; using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.Runtime; using Microsoft.Framework.Runtime;
@ -35,10 +36,10 @@ namespace PrecompilationWebSite
originalEnvironment, originalEnvironment,
newPath); newPath);
var collection = new ServiceCollection(); var collection = HostingServices.Create(provider);
collection.AddInstance<IApplicationEnvironment>(precompilationApplicationEnvironment); collection.AddInstance<IApplicationEnvironment>(precompilationApplicationEnvironment);
return collection.BuildServiceProvider(provider); return new DelegatingServiceProvider(provider, collection.BuildServiceProvider());
} }
private class PrecompilationApplicationEnvironment : IApplicationEnvironment private class PrecompilationApplicationEnvironment : IApplicationEnvironment
@ -80,5 +81,23 @@ namespace PrecompilationWebSite
get { return _originalApplicationEnvironment.RuntimeFramework; } get { return _originalApplicationEnvironment.RuntimeFramework; }
} }
} }
private class DelegatingServiceProvider : IServiceProvider
{
private readonly IServiceProvider _fallback;
private readonly IServiceProvider _services;
public DelegatingServiceProvider(IServiceProvider fallback, IServiceProvider services)
{
_fallback = fallback;
_services = services;
}
public object GetService(Type serviceType)
{
return _services.GetService(serviceType) ?? _fallback.GetService(serviceType);
}
}
} }
} }