Fix up the dynamic loading stuff

This commit is contained in:
Cyberboss
2018-07-25 10:34:46 -04:00
parent 10955fc3c8
commit 4f59d9717c
12 changed files with 84 additions and 27 deletions
+2
View File
@@ -60,6 +60,8 @@ after_test:
- dotnet publish src/Tgstation.Server.Host/Tgstation.Server.Host.csproj -o ../../artifacts/ServerHost -c %CONFIGURATION%
- dotnet publish src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj -o ../../artifacts/ServerConsole -c %CONFIGURATION%
- ps: Copy-Item -path "src/Tgstation.Server.Host.Service/bin/$env:CONFIGURATION" -destination artifacts/ServerService -recurse
- ps: Copy-Item -path "artifacts/ServerHost" -destination artifacts/ServerService/lib/Default -recurse
- ps: Copy-Item -path "artifacts/ServerHost" -destination artifacts/ServerConsole/lib/Default -recurse
- ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/artifacts/ServerHost/Tgstation.Server.Host.dll").FileVersion
deploy:
- provider: GitHub
@@ -34,7 +34,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.1.1" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
</ItemGroup>
@@ -0,0 +1,16 @@
using System.Threading.Tasks;
using Tgstation.Server.Host.Startup;
namespace Tgstation.Server.Host.Console.Debug
{
static class Program
{
internal static IServerFactory serverFactory = new ServerFactory();
static async Task Main(string[] args)
{
using (var server = serverFactory.CreateServer(args, "Updates"))
await server.RunAsync(default).ConfigureAwait(false);
}
}
}
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Tgstation.Server.Host\Tgstation.Server.Host.csproj" />
</ItemGroup>
</Project>
@@ -17,6 +17,10 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tgstation.Server.Host.Watchdog\Tgstation.Server.Host.Watchdog.csproj" />
</ItemGroup>
@@ -17,8 +17,4 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
</ItemGroup>
</Project>
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -13,6 +12,10 @@ namespace Tgstation.Server.Host.Watchdog
/// </summary>
sealed class IsolatedServerFactory : AssemblyLoadContext, IServerFactory
{
const string DllExtension = "dll";
static readonly string assemblyFileName = String.Join(".", nameof(Tgstation), nameof(Server), nameof(Host), DllExtension);
/// <summary>
/// The path of the <see cref="Assembly"/> to load
/// </summary>
@@ -22,7 +25,24 @@ namespace Tgstation.Server.Host.Watchdog
/// Construct a <see cref="IsolatedServerFactory"/>
/// </summary>
/// <param name="assemblyPath">The value of <see cref="assemblyPath"/></param>
public IsolatedServerFactory(string assemblyPath) => this.assemblyPath = assemblyPath ?? throw new ArgumentNullException(nameof(assemblyPath));
public IsolatedServerFactory(string assemblyPath)
{
this.assemblyPath = assemblyPath ?? throw new ArgumentNullException(nameof(assemblyPath));
Resolving += IsolatedServerFactory_Resolving;
}
//https://stackoverflow.com/a/40921746/3976486
Assembly IsolatedServerFactory_Resolving(AssemblyLoadContext context, AssemblyName assemblyName)
{
if (assemblyName.Name.EndsWith("resources", StringComparison.Ordinal))
return null;
var foundDll = Directory.GetFileSystemEntries(assemblyPath, String.Join(".", assemblyName.Name, DllExtension), SearchOption.AllDirectories).FirstOrDefault();
if (foundDll != default)
return context.LoadFromAssemblyPath(foundDll);
return context.LoadFromAssemblyName(assemblyName);
}
/// <summary>
/// Loads the <see cref="Assembly"/> at <see cref="assemblyPath"/> and creates an <see cref="IServer"/> from it
@@ -32,26 +52,15 @@ namespace Tgstation.Server.Host.Watchdog
/// <returns>A new <see cref="IServer"/></returns>
public IServer CreateServer(string[] args, string updatePath)
{
//help here: https://stackoverflow.com/questions/40908568/assembly-loading-in-net-core
var assembly = LoadFromAssemblyPath(Path.Combine(assemblyPath, assemblyFileName));
var oldCd = Environment.CurrentDirectory;
Directory.SetCurrentDirectory(Path.GetDirectoryName(assemblyPath));
try
{
var assembly = LoadFromAssemblyPath(assemblyPath);
//find the IServerFactory implementation
var serverFactoryInterfaceType = typeof(IServerFactory);
var serverFactoryImplementationType = assembly.GetTypes().Where(x => serverFactoryInterfaceType.IsAssignableFrom(x)).First();
//find the IServerFactory implementation
var serverFactoryInterfaceType = typeof(IServerFactory);
var serverFactoryImplementationType = assembly.GetTypes().Where(x => serverFactoryInterfaceType.IsAssignableFrom(x)).First();
var serverFactory = (IServerFactory)Activator.CreateInstance(serverFactoryImplementationType);
var serverFactory = (IServerFactory)Activator.CreateInstance(serverFactoryImplementationType);
return serverFactory.CreateServer(args, updatePath);
}
finally
{
Directory.SetCurrentDirectory(oldCd);
}
return serverFactory.CreateServer(args, updatePath);
}
//honestly have no idea what this is for, but the examples i see just return null and it seems to work just fine
@@ -18,6 +18,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
</ItemGroup>
@@ -46,7 +46,6 @@ namespace Tgstation.Server.Host.Watchdog
const string DefaultAssemblyPath = "Default";
var assemblyStoragePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lib");
var assemblyName = String.Join(".", nameof(Tgstation), nameof(Server), nameof(Host), "dll");
logger.LogInformation("Host watchdog starting...");
@@ -60,7 +59,7 @@ namespace Tgstation.Server.Host.Watchdog
logger.LogTrace("Atttempting to create new server factory...");
Guid updateGuid;
{ //forces serverFactory out of the picture once the scope ends
var serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(Path.Combine(nextAssemblyPath, assemblyName));
var serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(nextAssemblyPath);
using (var server = serverFactory.CreateServer(args, assemblyStoragePath))
{
logger.LogTrace("Running server...");
@@ -124,7 +124,7 @@ namespace Tgstation.Server.Host.Core
builder.EnableSensitiveDataLogging();
};
switch (databaseConfiguration.DatabaseType)
switch (databaseConfiguration?.DatabaseType ?? DatabaseType.Sqlite)
{
case DatabaseType.MySql:
services.AddDbContext<MySqlDatabaseContext>(ConfigureDatabase);
@@ -28,6 +28,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -36,6 +37,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+8
View File
@@ -102,6 +102,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "v4", "v4", "{057FAC33-CC31-
src\DMAPI\tgs\v4\commands.dm = src\DMAPI\tgs\v4\commands.dm
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tgstation.Server.Host.Console.Debug", "src\Tgstation.Server.Host.Console.Debug\Tgstation.Server.Host.Console.Debug.csproj", "{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -211,6 +213,12 @@ Global
{AA80A190-52E2-4BE3-BFEB-1F148D9E9007}.Docker|Any CPU.Build.0 = Release|Any CPU
{AA80A190-52E2-4BE3-BFEB-1F148D9E9007}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA80A190-52E2-4BE3-BFEB-1F148D9E9007}.Release|Any CPU.Build.0 = Release|Any CPU
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Docker|Any CPU.ActiveCfg = Debug|Any CPU
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Docker|Any CPU.Build.0 = Debug|Any CPU
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE