mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-07-20 20:43:47 +01:00
Port remaining C# to .NET Core 3.1
- Add IDatabaseCollection for abstracting DbSet.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<Import Project="../../build/Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<DebugType>Full</DebugType>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>Cyberboss</Authors>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Import Project="../../build/Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<DebugType>Full</DebugType>
|
||||
<Version>$(TgsClientVersion)</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net471</TargetFramework>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<RuntimeIdentifier>win</RuntimeIdentifier>
|
||||
<DebugType>Full</DebugType>
|
||||
<Version>$(TgsCoreVersion)</Version>
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
|
||||
var revisionInfo = await ApplyQuery(databaseContext.RevisionInformations).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// If the DB doesn't have it, check the local set
|
||||
if (revisionInfo == default)
|
||||
revisionInfo = databaseContext.RevisionInformations.Local.Where(x => x.CommitSha == repoSha && x.Instance.Id == instance.Id).FirstOrDefault();
|
||||
|
||||
@@ -669,6 +670,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
var contextUser = databaseContext.Users.Local.Where(x => x.Id == AuthenticationContext.User.Id).FirstOrDefault();
|
||||
if (contextUser == default)
|
||||
{
|
||||
// No reason to call the DB, just attach it
|
||||
contextUser = new Models.User
|
||||
{
|
||||
Id = AuthenticationContext.User.Id
|
||||
|
||||
@@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
@@ -67,9 +66,9 @@ namespace Tgstation.Server.Host.Core
|
||||
readonly IIOManager ioManager;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Microsoft.AspNetCore.Hosting.IHostingEnvironment"/> for the <see cref="Application"/>
|
||||
/// The <see cref="IWebHostEnvironment"/> for the <see cref="Application"/>
|
||||
/// </summary>
|
||||
readonly Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment;
|
||||
readonly IWebHostEnvironment hostingEnvironment;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TaskCompletionSource{TResult}"/> used for determining when the <see cref="Application"/> is <see cref="Ready(Exception)"/>
|
||||
@@ -91,7 +90,7 @@ namespace Tgstation.Server.Host.Core
|
||||
public Application(
|
||||
IConfiguration configuration,
|
||||
IAssemblyInformationProvider assemblyInformationProvider,
|
||||
Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment,
|
||||
IWebHostEnvironment hostingEnvironment,
|
||||
IIOManager ioManager)
|
||||
{
|
||||
this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
||||
@@ -146,11 +145,13 @@ namespace Tgstation.Server.Host.Core
|
||||
// temporarily build the service provider in it's current state
|
||||
// do it here so we can run the setup wizard if necessary
|
||||
// also allows us to get some options and other services we need for continued configuration
|
||||
#pragma warning disable ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices'
|
||||
using (var provider = services.BuildServiceProvider())
|
||||
#pragma warning restore ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices'
|
||||
{
|
||||
// run the wizard if necessary
|
||||
var setupWizard = provider.GetRequiredService<ISetupWizard>();
|
||||
var applicationLifetime = provider.GetRequiredService<Microsoft.AspNetCore.Hosting.IApplicationLifetime>();
|
||||
var applicationLifetime = provider.GetRequiredService<IHostApplicationLifetime>();
|
||||
var setupWizardRan = setupWizard.CheckRunWizard(applicationLifetime.ApplicationStopping).GetAwaiter().GetResult();
|
||||
|
||||
// load the configuration options we need
|
||||
@@ -242,9 +243,11 @@ namespace Tgstation.Server.Host.Core
|
||||
|
||||
// add mvc, configure the json serializer settings
|
||||
services
|
||||
.AddMvc()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
|
||||
.AddJsonOptions(options =>
|
||||
.AddMvc(options =>
|
||||
{
|
||||
options.EnableEndpointRouting = false;
|
||||
})
|
||||
.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.AllowInputFormatterExceptionMessages = true;
|
||||
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace Tgstation.Server.Host.Core
|
||||
readonly IConsole console;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IHostingEnvironment"/> for the <see cref="SetupWizard"/>
|
||||
/// The <see cref="IWebHostEnvironment"/> for the <see cref="SetupWizard"/>
|
||||
/// </summary>
|
||||
readonly IHostingEnvironment hostingEnvironment;
|
||||
readonly IWebHostEnvironment hostingEnvironment;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IApplication"/> for the <see cref="SetupWizard"/>
|
||||
@@ -85,7 +85,7 @@ namespace Tgstation.Server.Host.Core
|
||||
public SetupWizard(
|
||||
IIOManager ioManager,
|
||||
IConsole console,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IWebHostEnvironment hostingEnvironment,
|
||||
IApplication application,
|
||||
IDatabaseConnectionFactory dbConnectionFactory,
|
||||
IPlatformIdentifier platformIdentifier,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class DatabaseCollection<TModel> : IDatabaseCollection<TModel> where TModel : class
|
||||
{
|
||||
/// <summary>
|
||||
/// The backing <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
readonly DbSet<TModel> dbSet;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DatabaseCollection{TModel}"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
/// <param name="dbSet">The value of <see cref="dbSet"/>.</param>
|
||||
public DatabaseCollection(DbSet<TModel> dbSet)
|
||||
{
|
||||
this.dbSet = dbSet ?? throw new ArgumentNullException(nameof(dbSet));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<TModel> Local => dbSet.Local;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Type ElementType => dbSet.AsQueryable().ElementType;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Expression Expression => dbSet.AsQueryable().Expression;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IQueryProvider Provider => dbSet.AsQueryable().Provider;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Add(TModel model) => dbSet.Add(model);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void AddRange(IEnumerable<TModel> models) => dbSet.AddRange(models);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Attach(TModel model) => dbSet.Attach(model);
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<TModel> GetEnumerator() => dbSet.AsQueryable().GetEnumerator();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Remove(TModel model) => dbSet.Remove(model);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RemoveRange(IEnumerable<TModel> models) => dbSet.RemoveRange(models);
|
||||
|
||||
/// <inheritdoc />
|
||||
IEnumerator IEnumerable.GetEnumerator() => dbSet.AsQueryable().GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -19,43 +19,69 @@ namespace Tgstation.Server.Host.Database
|
||||
#pragma warning disable CA1506 // TODO: Decomplexify
|
||||
abstract class DatabaseContext<TParentContext> : DbContext, IDatabaseContext where TParentContext : DbContext
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="User"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<User> Users { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="Instance"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<Instance> Instances { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="CompileJob"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<CompileJob> CompileJobs { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="RevisionInformation"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<RevisionInformation> RevisionInformations { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="Models.DreamMakerSettings"/> in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<DreamMakerSettings> DreamMakerSettings { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="ChatBot"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<ChatBot> ChatBots { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="Models.DreamDaemonSettings"/> in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<DreamDaemonSettings> DreamDaemonSettings { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="Models.RepositorySettings"/> in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<RepositorySettings> RepositorySettings { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="InstanceUser"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<InstanceUser> InstanceUsers { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="ChatChannel"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<ChatChannel> ChatChannels { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="Job"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<Job> Jobs { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="ReattachInformation"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<ReattachInformation> ReattachInformations { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// The <see cref="WatchdogReattachInformation"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
|
||||
/// </summary>
|
||||
public DbSet<WatchdogReattachInformation> WatchdogReattachInformations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -83,11 +109,115 @@ namespace Tgstation.Server.Host.Database
|
||||
/// </summary>
|
||||
protected abstract DatabaseType DatabaseType { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<User> IDatabaseContext.Users => usersCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<Instance> IDatabaseContext.Instances => instancesCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<InstanceUser> IDatabaseContext.InstanceUsers => instanceUsersCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<Job> IDatabaseContext.Jobs => jobsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<CompileJob> IDatabaseContext.CompileJobs => compileJobsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<RevisionInformation> IDatabaseContext.RevisionInformations => revisionInformationsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<DreamMakerSettings> IDatabaseContext.DreamMakerSettings => dreamMakerSettingsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<DreamDaemonSettings> IDatabaseContext.DreamDaemonSettings => dreamDaemonSettingsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<ChatBot> IDatabaseContext.ChatBots => chatBotsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<ChatChannel> IDatabaseContext.ChatChannels => chatChannelsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<RepositorySettings> IDatabaseContext.RepositorySettings => repositorySettingsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<ReattachInformation> IDatabaseContext.ReattachInformations => reattachInformationsCollection;
|
||||
|
||||
/// <inheritdoc />
|
||||
IDatabaseCollection<WatchdogReattachInformation> IDatabaseContext.WatchdogReattachInformations => watchdogReattachInformationsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/>
|
||||
/// </summary>
|
||||
readonly IDatabaseSeeder databaseSeeder;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.Users"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<User> usersCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.Instances"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<Instance> instancesCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.CompileJobs"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<CompileJob> compileJobsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.InstanceUsers"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<InstanceUser> instanceUsersCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.Jobs"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<Job> jobsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.RevisionInformations"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<RevisionInformation> revisionInformationsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.DreamMakerSettings"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<DreamMakerSettings> dreamMakerSettingsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.DreamDaemonSettings"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<DreamDaemonSettings> dreamDaemonSettingsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.ChatBots"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<ChatBot> chatBotsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.ChatChannels"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<ChatChannel> chatChannelsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.RepositorySettings"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<RepositorySettings> repositorySettingsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.ReattachInformations"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<ReattachInformation> reattachInformationsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="IDatabaseContext.WatchdogReattachInformations"/>.
|
||||
/// </summary>
|
||||
readonly IDatabaseCollection<WatchdogReattachInformation> watchdogReattachInformationsCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="DatabaseContext{TParentContext}"/>
|
||||
/// </summary>
|
||||
@@ -100,6 +230,20 @@ namespace Tgstation.Server.Host.Database
|
||||
DatabaseConfiguration = databaseConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions));
|
||||
this.databaseSeeder = databaseSeeder ?? throw new ArgumentNullException(nameof(databaseSeeder));
|
||||
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
usersCollection = new DatabaseCollection<User>(Users);
|
||||
instancesCollection = new DatabaseCollection<Instance>(Instances);
|
||||
instanceUsersCollection = new DatabaseCollection<InstanceUser>(InstanceUsers);
|
||||
compileJobsCollection = new DatabaseCollection<CompileJob>(CompileJobs);
|
||||
repositorySettingsCollection = new DatabaseCollection<RepositorySettings>(RepositorySettings);
|
||||
dreamMakerSettingsCollection = new DatabaseCollection<DreamMakerSettings>(DreamMakerSettings);
|
||||
dreamDaemonSettingsCollection = new DatabaseCollection<DreamDaemonSettings>(DreamDaemonSettings);
|
||||
chatBotsCollection = new DatabaseCollection<ChatBot>(ChatBots);
|
||||
chatChannelsCollection = new DatabaseCollection<ChatChannel>(ChatChannels);
|
||||
revisionInformationsCollection = new DatabaseCollection<RevisionInformation>(RevisionInformations);
|
||||
jobsCollection = new DatabaseCollection<Job>(Jobs);
|
||||
reattachInformationsCollection = new DatabaseCollection<ReattachInformation>(ReattachInformations);
|
||||
watchdogReattachInformationsCollection = new DatabaseCollection<WatchdogReattachInformation>(WatchdogReattachInformations);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -166,7 +310,7 @@ namespace Tgstation.Server.Host.Database
|
||||
else
|
||||
Logger.LogDebug("No migrations to apply.");
|
||||
|
||||
wasEmpty |= (await Users.CountAsync(cancellationToken).ConfigureAwait(false)) == 0;
|
||||
wasEmpty |= (await Users.AsQueryable().CountAsync(cancellationToken).ConfigureAwait(false)) == 0;
|
||||
|
||||
if (wasEmpty)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a database table.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of model.</typeparam>
|
||||
public interface IDatabaseCollection<TModel> : IQueryable<TModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="IEnumerable{T}"/> of <typeparamref name="TModel"/>s prioritizing in the working set.
|
||||
/// </summary>
|
||||
IEnumerable<TModel> Local { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Add a given <paramref name="model"/> to the the working set.
|
||||
/// </summary>
|
||||
/// <param name="model">The <typeparamref name="TModel"/> model to add.</param>
|
||||
void Add(TModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Remove a given <paramref name="model"/> from the the working set.
|
||||
/// </summary>
|
||||
/// <param name="model">The <typeparamref name="TModel"/> model to remove.</param>
|
||||
void Remove(TModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Attach a given <paramref name="model"/> to the the working set.
|
||||
/// </summary>
|
||||
/// <param name="model">The <typeparamref name="TModel"/> model to add.</param>
|
||||
void Attach(TModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Add a range of <paramref name="models"/> to the <see cref="IDatabaseCollection{TModel}"/>.
|
||||
/// </summary>
|
||||
/// <param name="models">An <see cref="IEnumerable{T}"/> of <typeparamref name="TModel"/>s to add.</param>
|
||||
void AddRange(IEnumerable<TModel> models);
|
||||
|
||||
/// <summary>
|
||||
/// Remove a range of <paramref name="models"/> from the <see cref="IDatabaseCollection{TModel}"/>.
|
||||
/// </summary>
|
||||
/// <param name="models">An <see cref="IEnumerable{T}"/> of <typeparamref name="TModel"/>s to remove.</param>
|
||||
void RemoveRange(IEnumerable<TModel> models);
|
||||
}
|
||||
}
|
||||
@@ -14,67 +14,67 @@ namespace Tgstation.Server.Host.Database
|
||||
/// <summary>
|
||||
/// The <see cref="User"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<User> Users { get; }
|
||||
IDatabaseCollection<User> Users { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Instance"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<Instance> Instances { get; }
|
||||
IDatabaseCollection<Instance> Instances { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="InstanceUser"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<InstanceUser> InstanceUsers { get; }
|
||||
IDatabaseCollection<InstanceUser> InstanceUsers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Job"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<Job> Jobs { get; }
|
||||
IDatabaseCollection<Job> Jobs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="CompileJob"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<CompileJob> CompileJobs { get; }
|
||||
IDatabaseCollection<CompileJob> CompileJobs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RevisionInformation"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<RevisionInformation> RevisionInformations { get; }
|
||||
IDatabaseCollection<RevisionInformation> RevisionInformations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Models.DreamMakerSettings"/> in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<DreamMakerSettings> DreamMakerSettings { get; set; }
|
||||
IDatabaseCollection<DreamMakerSettings> DreamMakerSettings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Models.DreamDaemonSettings"/> in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<DreamDaemonSettings> DreamDaemonSettings { get; set; }
|
||||
IDatabaseCollection<DreamDaemonSettings> DreamDaemonSettings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ChatBot"/>s in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<ChatBot> ChatBots { get; set; }
|
||||
IDatabaseCollection<ChatBot> ChatBots { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ChatChannel"/> in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<ChatChannel> ChatChannels { get; set; }
|
||||
IDatabaseCollection<ChatChannel> ChatChannels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Models.RepositorySettings"/> in the <see cref="IDatabaseContext"/>
|
||||
/// </summary>
|
||||
DbSet<RepositorySettings> RepositorySettings { get; set; }
|
||||
IDatabaseCollection<RepositorySettings> RepositorySettings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DbSet{TEntity}"/> for <see cref="ReattachInformation"/>s
|
||||
/// </summary>
|
||||
DbSet<ReattachInformation> ReattachInformations { get; set; }
|
||||
IDatabaseCollection<ReattachInformation> ReattachInformations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DbSet{TEntity}"/> for <see cref="WatchdogReattachInformation"/>s
|
||||
/// </summary>
|
||||
DbSet<WatchdogReattachInformation> WatchdogReattachInformations { get; set; }
|
||||
IDatabaseCollection<WatchdogReattachInformation> WatchdogReattachInformations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Saves changes made to the <see cref="IDatabaseContext"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
@@ -26,9 +26,9 @@ namespace Tgstation.Server.Host
|
||||
public bool WatchdogPresent => updatePath != null;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IWebHostBuilder"/> for the <see cref="Server"/>
|
||||
/// The <see cref="IHostBuilder"/> for the <see cref="Server"/>
|
||||
/// </summary>
|
||||
readonly IWebHostBuilder webHostBuilder;
|
||||
readonly IHostBuilder hostBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="Server"/>.
|
||||
@@ -73,16 +73,16 @@ namespace Tgstation.Server.Host
|
||||
/// <summary>
|
||||
/// Construct a <see cref="Server"/>
|
||||
/// </summary>
|
||||
/// <param name="webHostBuilder">The value of <see cref="webHostBuilder"/></param>
|
||||
/// <param name="hostBuilder">The value of <see cref="hostBuilder"/></param>
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
|
||||
/// <param name="updatePath">The value of <see cref="updatePath"/></param>
|
||||
public Server(IWebHostBuilder webHostBuilder, IIOManager ioManager, string updatePath)
|
||||
public Server(IHostBuilder hostBuilder, IIOManager ioManager, string updatePath)
|
||||
{
|
||||
this.webHostBuilder = webHostBuilder ?? throw new ArgumentNullException(nameof(webHostBuilder));
|
||||
this.hostBuilder = hostBuilder ?? throw new ArgumentNullException(nameof(hostBuilder));
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
this.updatePath = updatePath;
|
||||
|
||||
webHostBuilder.ConfigureServices(serviceCollection => serviceCollection.AddSingleton<IServerControl>(this));
|
||||
hostBuilder.ConfigureServices(serviceCollection => serviceCollection.AddSingleton<IServerControl>(this));
|
||||
|
||||
restartHandlers = new List<IRestartHandler>();
|
||||
}
|
||||
@@ -129,15 +129,15 @@ namespace Tgstation.Server.Host
|
||||
fsWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
using (var webHost = webHostBuilder.Build())
|
||||
using (var host = hostBuilder.Build())
|
||||
try
|
||||
{
|
||||
logger = webHost.Services.GetRequiredService<ILogger<Server>>();
|
||||
logger = host.Services.GetRequiredService<ILogger<Server>>();
|
||||
using (cancellationToken.Register(() => logger.LogInformation("Process termination requested!")))
|
||||
{
|
||||
var generalConfigurationOptions = webHost.Services.GetRequiredService<IOptions<GeneralConfiguration>>();
|
||||
var generalConfigurationOptions = host.Services.GetRequiredService<IOptions<GeneralConfiguration>>();
|
||||
generalConfiguration = generalConfigurationOptions.Value;
|
||||
await webHost.RunAsync(cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
await host.RunAsync(cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Tgstation.Server.Host.Core;
|
||||
@@ -44,21 +44,26 @@ namespace Tgstation.Server.Host
|
||||
/// <inheritdoc />
|
||||
public IServer CreateServer(string[] args, string updatePath)
|
||||
{
|
||||
var webHost = WebHost.CreateDefaultBuilder(args ?? throw new ArgumentNullException(nameof(args)))
|
||||
var hostBuilder = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(
|
||||
args ?? throw new ArgumentNullException(nameof(args)))
|
||||
.ConfigureAppConfiguration((context, configurationBuilder) => configurationBuilder.SetBasePath(Directory.GetCurrentDirectory()))
|
||||
.ConfigureServices(serviceCollection =>
|
||||
{
|
||||
serviceCollection.AddSingleton(IOManager);
|
||||
serviceCollection.AddSingleton(assemblyInformationProvider);
|
||||
})
|
||||
.UseStartup<Application>()
|
||||
.SuppressStatusMessages(true)
|
||||
.UseShutdownTimeout(TimeSpan.FromMinutes(1));
|
||||
.ConfigureWebHostDefaults(webHostBuilder =>
|
||||
{
|
||||
webHostBuilder
|
||||
.UseStartup<Application>()
|
||||
.SuppressStatusMessages(true)
|
||||
.UseShutdownTimeout(TimeSpan.FromMinutes(1));
|
||||
});
|
||||
|
||||
if(updatePath != null)
|
||||
webHost.UseContentRoot(Path.GetDirectoryName(assemblyInformationProvider.Path));
|
||||
hostBuilder.UseContentRoot(Path.GetDirectoryName(assemblyInformationProvider.Path));
|
||||
|
||||
return new Server(webHost, IOManager, updatePath);
|
||||
return new Server(hostBuilder, IOManager, updatePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,24 @@
|
||||
<Import Project="../../build/Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<DebugType>Full</DebugType>
|
||||
<Version>$(TgsCoreVersion)</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
<DocumentationFile>bin\Release\netcoreapp2.1\Tgstation.Server.Host.xml</DocumentationFile>
|
||||
<NoWarn>API1000</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;SA1652;CA1063</NoWarn>
|
||||
<NoWarn>API1000</NoWarn>
|
||||
<DocumentationFile>bin\Debug\netcoreapp2.1\Tgstation.Server.Host.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -49,27 +51,27 @@
|
||||
<PackageReference Include="Cyberboss.SmartIrc4net.Standard" Version="0.4.6" />
|
||||
<PackageReference Include="Discord.Net.WebSocket" Version="2.2.0" />
|
||||
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0034" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.6">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageReference Include="Octokit" Version="0.47.0" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.1" />
|
||||
<!-- If this is updated, be sure to update the reference in the README.md -->
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.6" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
|
||||
@@ -79,11 +81,11 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.3.2" />
|
||||
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.7.0" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="4.7.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.0" />
|
||||
<PackageReference Include="Wangkanai.Detection.Browser" Version="2.0.0" />
|
||||
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="2.0.32" />
|
||||
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.0.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net471</TargetFramework>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
@@ -34,7 +33,7 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(mockConfiguration.Object, mockAssemblyInfo.Object, null, null));
|
||||
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
var mockHostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(mockConfiguration.Object, mockAssemblyInfo.Object, mockHostingEnvironment.Object, null));
|
||||
|
||||
var app = new Application(mockConfiguration.Object, mockAssemblyInfo.Object, mockHostingEnvironment.Object, Mock.Of<IIOManager>());
|
||||
@@ -67,7 +66,7 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
public Task<bool> CheckRunWizard(CancellationToken cancellationToken) => Task.FromResult(true);
|
||||
}
|
||||
|
||||
class MockApplicationLifetime : IApplicationLifetime
|
||||
class MockHostApplicationLifetime : IHostApplicationLifetime
|
||||
{
|
||||
public CancellationToken ApplicationStarted => default;
|
||||
|
||||
@@ -77,42 +76,5 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
|
||||
public void StopApplication() { }
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConfigureServicesThrowsWhenSetupWizardConfigurationDemands()
|
||||
{
|
||||
var mockConfiguration = new Mock<IConfiguration>();
|
||||
var mockAssemblyInfo = new Mock<IAssemblyInformationProvider>();
|
||||
mockAssemblyInfo.SetupGet(x => x.Name).Returns(typeof(Application).Assembly.GetName());
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
|
||||
var app = new Application(mockConfiguration.Object, mockAssemblyInfo.Object, mockHostingEnvironment.Object, Mock.Of<IIOManager>());
|
||||
|
||||
var mockOptions = new Mock<IOptions<GeneralConfiguration>>();
|
||||
mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration
|
||||
{
|
||||
SetupWizardMode = SetupWizardMode.Only
|
||||
}).Verifiable();
|
||||
|
||||
var fakeServiceDescriptor = new List<ServiceDescriptor>()
|
||||
{
|
||||
new ServiceDescriptor(typeof(IApplicationLifetime), typeof(MockApplicationLifetime), ServiceLifetime.Singleton),
|
||||
new ServiceDescriptor(typeof(ISetupWizard), typeof(MockSetupWizard), ServiceLifetime.Singleton),
|
||||
new ServiceDescriptor(typeof(IOptions<GeneralConfiguration>), mockOptions.Object)
|
||||
};
|
||||
|
||||
var mockServiceCollection = new Mock<IServiceCollection>();
|
||||
|
||||
var mockConfigSection = new Mock<IConfigurationSection>();
|
||||
|
||||
mockConfiguration.Setup(x => x.GetSection(It.IsNotNull<string>())).Returns(mockConfigSection.Object).Verifiable();
|
||||
mockServiceCollection.Setup(x => x.GetEnumerator()).Returns(() => fakeServiceDescriptor.GetEnumerator()).Verifiable();
|
||||
|
||||
Assert.ThrowsException<OperationCanceledException>(() => app.ConfigureServices(mockServiceCollection.Object));
|
||||
|
||||
mockOptions.VerifyAll();
|
||||
mockConfiguration.VerifyAll();
|
||||
mockServiceCollection.VerifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new SetupWizard(mockIOManager.Object, null, null, null, null, null, null, null, null));
|
||||
var mockConsole = new Mock<IConsole>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new SetupWizard(mockIOManager.Object, mockConsole.Object, null, null, null, null, null, null, null));
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
var mockHostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new SetupWizard(mockIOManager.Object, mockConsole.Object, mockHostingEnvironment.Object, null, null, null, null, null, null));
|
||||
var mockApplication = new Mock<IApplication>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new SetupWizard(mockIOManager.Object, mockConsole.Object, mockHostingEnvironment.Object, mockApplication.Object, null, null, null, null, null));
|
||||
@@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
{
|
||||
var mockIOManager = new Mock<IIOManager>();
|
||||
var mockConsole = new Mock<IConsole>();
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
var mockHostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
var mockApplication = new Mock<IApplication>();
|
||||
var mockDBConnectionFactory = new Mock<IDatabaseConnectionFactory>();
|
||||
var mockLogger = new Mock<ILogger<SetupWizard>>();
|
||||
@@ -76,7 +76,7 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
|
||||
mockConsole.SetupGet(x => x.Available).Returns(true).Verifiable();
|
||||
mockIOManager.Setup(x => x.FileExists(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(true)).Verifiable();
|
||||
mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(Encoding.UTF8.GetBytes("cucked"))).Verifiable();
|
||||
mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(Encoding.UTF8.GetBytes("less profane"))).Verifiable();
|
||||
mockIOManager.Setup(x => x.WriteAllBytes(It.IsNotNull<string>(), It.IsNotNull<byte[]>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask).Verifiable();
|
||||
|
||||
var mockSuccessCommand = new Mock<DbCommand>();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
Reference in New Issue
Block a user