Consume host resolver source package from dotnet/runtime (#22962)

This commit is contained in:
John Luo 2020-06-15 15:21:58 -07:00 committed by GitHub
parent a861d18d24
commit b284229790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 9 additions and 234 deletions

View File

@ -46,6 +46,7 @@ and are generated based on the last package release.
<LatestPackageReference Include="Microsoft.Extensions.FileProviders.Composite" Version="$(MicrosoftExtensionsFileProvidersCompositePackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="$(MicrosoftExtensionsFileProvidersPhysicalPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="$(MicrosoftExtensionsFileSystemGlobbingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.HostFactoryResolver.Sources" Version="$(MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsHostingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsHttpPackageVersion)" />

View File

@ -113,6 +113,10 @@
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>533e9b7dbb5ab9f63e74f95d8cae78171dafc31f</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="5.0.0-preview.7.20314.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>533e9b7dbb5ab9f63e74f95d8cae78171dafc31f</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-preview.7.20314.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>533e9b7dbb5ab9f63e74f95d8cae78171dafc31f</Sha>

View File

@ -90,6 +90,7 @@
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsFileProvidersCompositePackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsHostingAbstractionsPackageVersion>
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsHostingPackageVersion>
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.7.20314.1</MicrosoftExtensionsHttpPackageVersion>

View File

@ -12,8 +12,7 @@
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.Hosting" />
<Reference Include="System.IO.Pipelines" />
<Compile Include="$(SharedSourceRoot)HostFactoryResolver\*.cs" />
<Reference Include="Microsoft.Extensions.HostFactoryResolver.Sources" />
</ItemGroup>
</Project>

View File

@ -17,8 +17,7 @@
<Reference Include="Microsoft.AspNetCore.Mvc.Core" />
<Reference Include="Microsoft.Extensions.DependencyModel" />
<Reference Include="Microsoft.Extensions.Hosting" />
<Compile Include="$(SharedSourceRoot)HostFactoryResolver\*.cs" />
<Reference Include="Microsoft.Extensions.HostFactoryResolver.Sources" />
</ItemGroup>
<ItemGroup>

View File

@ -1,112 +0,0 @@
// 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 System.Reflection;
namespace Microsoft.Extensions.Hosting
{
internal class HostFactoryResolver
{
public static readonly string BuildWebHost = nameof(BuildWebHost);
public static readonly string CreateWebHostBuilder = nameof(CreateWebHostBuilder);
public static readonly string CreateHostBuilder = nameof(CreateHostBuilder);
public static Func<string[], TWebHost> ResolveWebHostFactory<TWebHost>(Assembly assembly)
{
return ResolveFactory<TWebHost>(assembly, BuildWebHost);
}
public static Func<string[], TWebHostBuilder> ResolveWebHostBuilderFactory<TWebHostBuilder>(Assembly assembly)
{
return ResolveFactory<TWebHostBuilder>(assembly, CreateWebHostBuilder);
}
public static Func<string[], THostBuilder> ResolveHostBuilderFactory<THostBuilder>(Assembly assembly)
{
return ResolveFactory<THostBuilder>(assembly, CreateHostBuilder);
}
private static Func<string[], T> ResolveFactory<T>(Assembly assembly, string name)
{
var programType = assembly?.EntryPoint?.DeclaringType;
if (programType == null)
{
return null;
}
var factory = programType.GetTypeInfo().GetDeclaredMethod(name);
if (!IsFactory<T>(factory))
{
return null;
}
return args => (T)factory.Invoke(null, new object[] { args });
}
// TReturn Factory(string[] args);
private static bool IsFactory<TReturn>(MethodInfo factory)
{
return factory != null
&& typeof(TReturn).IsAssignableFrom(factory.ReturnType)
&& factory.GetParameters().Length == 1
&& typeof(string[]).Equals(factory.GetParameters()[0].ParameterType);
}
// Used by EF tooling without any Hosting references. Looses some return type safety checks.
public static Func<string[], IServiceProvider> ResolveServiceProviderFactory(Assembly assembly)
{
// Prefer the older patterns by default for back compat.
var webHostFactory = ResolveWebHostFactory<object>(assembly);
if (webHostFactory != null)
{
return args =>
{
var webHost = webHostFactory(args);
return GetServiceProvider(webHost);
};
}
var webHostBuilderFactory = ResolveWebHostBuilderFactory<object>(assembly);
if (webHostBuilderFactory != null)
{
return args =>
{
var webHostBuilder = webHostBuilderFactory(args);
var webHost = Build(webHostBuilder);
return GetServiceProvider(webHost);
};
}
var hostBuilderFactory = ResolveHostBuilderFactory<object>(assembly);
if (hostBuilderFactory != null)
{
return args =>
{
var hostBuilder = hostBuilderFactory(args);
var host = Build(hostBuilder);
return GetServiceProvider(host);
};
}
return null;
}
private static object Build(object builder)
{
var buildMethod = builder.GetType().GetMethod("Build");
return buildMethod?.Invoke(builder, Array.Empty<object>());
}
private static IServiceProvider GetServiceProvider(object host)
{
if (host == null)
{
return null;
}
var hostType = host.GetType();
var servicesProperty = hostType.GetTypeInfo().GetDeclaredProperty("Services");
return (IServiceProvider)servicesProperty.GetValue(host);
}
}
}

View File

@ -1,116 +0,0 @@
// 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 MockHostTypes;
using System;
using Xunit;
namespace Microsoft.Extensions.Hosting.Tests
{
public class HostFactoryResolverTests
{
[Fact]
public void BuildWebHostPattern_CanFindWebHost()
{
var factory = HostFactoryResolver.ResolveWebHostFactory<IWebHost>(typeof(BuildWebHostPatternTestSite.Program).Assembly);
Assert.NotNull(factory);
Assert.IsAssignableFrom<IWebHost>(factory(Array.Empty<string>()));
}
[Fact]
public void BuildWebHostPattern_CanFindServiceProvider()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(BuildWebHostPatternTestSite.Program).Assembly);
Assert.NotNull(factory);
Assert.IsAssignableFrom<IServiceProvider>(factory(Array.Empty<string>()));
}
[Fact]
public void BuildWebHostPattern__Invalid_CantFindWebHost()
{
var factory = HostFactoryResolver.ResolveWebHostFactory<IWebHost>(typeof(BuildWebHostInvalidSignature.Program).Assembly);
Assert.Null(factory);
}
[Fact]
public void BuildWebHostPattern__Invalid_CantFindServiceProvider()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(BuildWebHostInvalidSignature.Program).Assembly);
Assert.Null(factory);
}
[Fact]
public void CreateWebHostBuilderPattern_CanFindWebHostBuilder()
{
var factory = HostFactoryResolver.ResolveWebHostBuilderFactory<IWebHostBuilder>(typeof(CreateWebHostBuilderPatternTestSite.Program).Assembly);
Assert.NotNull(factory);
Assert.IsAssignableFrom<IWebHostBuilder>(factory(Array.Empty<string>()));
}
[Fact]
public void CreateWebHostBuilderPattern_CanFindServiceProvider()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(CreateWebHostBuilderPatternTestSite.Program).Assembly);
Assert.NotNull(factory);
Assert.IsAssignableFrom<IServiceProvider>(factory(Array.Empty<string>()));
}
[Fact]
public void CreateWebHostBuilderPattern__Invalid_CantFindWebHostBuilder()
{
var factory = HostFactoryResolver.ResolveWebHostBuilderFactory<IWebHostBuilder>(typeof(CreateWebHostBuilderInvalidSignature.Program).Assembly);
Assert.Null(factory);
}
[Fact]
public void CreateWebHostBuilderPattern__InvalidReturnType_CanFindServiceProvider()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(CreateWebHostBuilderInvalidSignature.Program).Assembly);
Assert.NotNull(factory);
Assert.Null(factory(Array.Empty<string>()));
}
[Fact]
public void CreateHostBuilderPattern_CanFindHostBuilder()
{
var factory = HostFactoryResolver.ResolveHostBuilderFactory<MockHostTypes.IHostBuilder>(typeof(CreateHostBuilderPatternTestSite.Program).Assembly);
Assert.NotNull(factory);
Assert.IsAssignableFrom<MockHostTypes.IHostBuilder>(factory(Array.Empty<string>()));
}
[Fact]
public void CreateHostBuilderPattern_CanFindServiceProvider()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(CreateHostBuilderPatternTestSite.Program).Assembly);
Assert.NotNull(factory);
Assert.IsAssignableFrom<IServiceProvider>(factory(Array.Empty<string>()));
}
[Fact]
public void CreateHostBuilderPattern__Invalid_CantFindHostBuilder()
{
var factory = HostFactoryResolver.ResolveHostBuilderFactory<MockHostTypes.IHostBuilder>(typeof(CreateHostBuilderInvalidSignature.Program).Assembly);
Assert.Null(factory);
}
[Fact]
public void CreateHostBuilderPattern__Invalid_CantFindServiceProvider()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(CreateHostBuilderInvalidSignature.Program).Assembly);
Assert.Null(factory);
}
}
}

View File

@ -14,7 +14,6 @@
<Compile Include="$(SharedSourceRoot)ClosedGenericMatcher\*.cs" Link="Shared\ClosedGenericMatcher\%(Filename)%(Extension)"/>
<Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" Link="Shared\CopyOnWriteDictionary\%(Filename)%(Extension)"/>
<Compile Include="$(SharedSourceRoot)HashCodeCombiner\**\*.cs" Link="Shared\HashCodeCombiner\%(Filename)%(Extension)"/>
<Compile Include="$(SharedSourceRoot)HostFactoryResolver\**\*.cs" Link="Shared\HostFactoryResolver\%(Filename)%(Extension)"/>
<Compile Include="$(SharedSourceRoot)runtime\*.cs" Link="Shared\runtime\%(Filename)%(Extension)"/>
<Compile Include="$(SharedSourceRoot)runtime\Http2\**\*.cs" Link="Shared\runtime\Http2\%(Filename)%(Extension)"/>
<Compile Include="$(SharedSourceRoot)runtime\Http3\**\*.cs" Link="Shared\runtime\Http3\%(Filename)%(Extension)"/>

View File

@ -15,9 +15,9 @@
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.HostFactoryResolver.Sources" />
<Compile Include="$(SharedSourceRoot)CommandLineUtils\**\*.cs" />
<Compile Include="$(ToolSharedSourceRoot)CommandLine/**/*.cs" />
<Compile Include="$(SharedSourceRoot)HostFactoryResolver\*.cs" />
</ItemGroup>
<Target Name="BuildX86" BeforeTargets="Build" Condition=" '$(TargetFramework)' == 'net461' And '$(Platform)' != 'x86' ">