Fixing database configuration

There is still broken dependencies when the module is in another assembly
This commit is contained in:
Zoe Roux 2021-05-04 17:59:05 +02:00
parent 709e12191d
commit feb643da2e
10 changed files with 120 additions and 68 deletions

View File

@ -16,13 +16,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="4.1.1" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.1" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.1" />
<PackageReference Include="IdentityServer4.EntityFramework.Storage" Version="4.1.1" />
<PackageReference Include="IdentityServer4.Storage" Version="4.1.1" />
<PackageReference Include="IdentityServer4" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework.Storage" Version="4.1.2" />
<PackageReference Include="IdentityServer4.Storage" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
</ItemGroup>
<ItemGroup>

View File

@ -84,6 +84,20 @@ namespace Kyoo
return Set<Link<T1, T2>>();
}
/// <summary>
/// The default constructor
/// </summary>
protected DatabaseContext() { }
/// <summary>
/// Create a new <see cref="DatabaseContext"/> using specific options
/// </summary>
/// <param name="options">The options to use.</param>
protected DatabaseContext(DbContextOptions options)
: base(options)
{ }
/// <summary>
/// Set basic configurations (like preventing query tracking)
/// </summary>

View File

@ -12,10 +12,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Npgsql" Version="5.0.3" />
</ItemGroup>
<ItemGroup>

View File

@ -16,11 +16,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.5.1" />
</ItemGroup>
<ItemGroup>

View File

@ -22,6 +22,11 @@ namespace Kyoo.Postgresql
/// </summary>
private readonly bool _debugMode;
/// <summary>
/// Should the configure step be skipped? This is used when the database is created via DbContextOptions.
/// </summary>
private readonly bool _skipConfigure;
/// <summary>
/// A basic constructor that set default values (query tracker behaviors, mapping enums...)
/// </summary>
@ -32,6 +37,19 @@ namespace Kyoo.Postgresql
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
}
/// <summary>
/// Create a new <see cref="PostgresContext"/> using specific options
/// </summary>
/// <param name="options">The options to use.</param>
public PostgresContext(DbContextOptions options)
: base(options)
{
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
NpgsqlConnection.GlobalTypeMapper.MapEnum<ItemType>();
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
_skipConfigure = true;
}
/// <summary>
/// A basic constructor that set default values (query tracker behaviors, mapping enums...)
/// </summary>
@ -48,11 +66,14 @@ namespace Kyoo.Postgresql
/// </summary>
/// <param name="optionsBuilder">An option builder to fill.</param>
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!_skipConfigure)
{
optionsBuilder.UseNpgsql(_connection);
if (_debugMode)
optionsBuilder.EnableDetailedErrors()
.EnableSensitiveDataLogging();
optionsBuilder.EnableDetailedErrors().EnableSensitiveDataLogging();
}
base.OnConfiguring(optionsBuilder);
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -59,9 +60,16 @@ namespace Kyoo.Postgresql
/// <inheritdoc />
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
{
services.AddScoped<DatabaseContext>(_ => new PostgresContext(
_configuration.GetDatabaseConnection("postgres"),
_environment.IsDevelopment()));
services.AddDbContext<DatabaseContext, PostgresContext>(x =>
{
x.UseNpgsql(_configuration.GetDatabaseConnection("postgres"));
if (_environment.IsDevelopment())
x.EnableDetailedErrors().EnableSensitiveDataLogging();
});
// services.AddScoped<DatabaseContext>(_ => new PostgresContext(
// _configuration.GetDatabaseConnection("postgres"),
// _environment.IsDevelopment()));
// services.AddScoped<DbContext>(x => x.GetRequiredService<PostgresContext>());
}
}
}

View File

@ -14,14 +14,14 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.3.0">
<PackageReference Include="coverlet.collector" Version="3.0.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@ -69,16 +69,12 @@ namespace Kyoo.Controllers
return _plugins;
}
/// <inheritdoc />
public void LoadPlugins(ICollection<IPlugin> plugins)
{
string pluginFolder = _config.GetValue<string>("plugins");
if (!Directory.Exists(pluginFolder))
Directory.CreateDirectory(pluginFolder);
_logger.LogTrace("Loading new plugins...");
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
plugins = pluginsPaths.SelectMany(path =>
/// <summary>
/// Load a single plugin and return all IPlugin implementations contained in the Assembly.
/// </summary>
/// <param name="path">The path of the dll</param>
/// <returns>The list of dlls in hte assembly</returns>
private IPlugin[] LoadPlugin(string path)
{
path = Path.GetFullPath(path);
try
@ -96,9 +92,23 @@ namespace Kyoo.Controllers
_logger.LogError(ex, "Could not load the plugin at {Path}", path);
return Array.Empty<IPlugin>();
}
}).Concat(plugins).ToList();
}
ICollection<Type> available = GetProvidedTypes();
/// <inheritdoc />
public void LoadPlugins(ICollection<IPlugin> plugins)
{
string pluginFolder = _config.GetValue<string>("plugins");
if (!Directory.Exists(pluginFolder))
Directory.CreateDirectory(pluginFolder);
_logger.LogTrace("Loading new plugins...");
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
plugins = plugins.Concat(pluginsPaths.SelectMany(LoadPlugin))
.GroupBy(x => x.Name)
.Select(x => x.First())
.ToList();
ICollection<Type> available = GetProvidedTypes(plugins);
_plugins.AddRange(plugins.Where(plugin =>
{
Type missing = plugin.Requires.FirstOrDefault(x => available.All(y => !y.IsAssignableTo(x)));
@ -119,7 +129,7 @@ namespace Kyoo.Controllers
/// <inheritdoc />
public void ConfigureServices(IServiceCollection services)
{
ICollection<Type> available = GetProvidedTypes();
ICollection<Type> available = GetProvidedTypes(_plugins);
foreach (IPlugin plugin in _plugins)
plugin.Configure(services, available);
}
@ -134,11 +144,12 @@ namespace Kyoo.Controllers
/// <summary>
/// Get the list of types provided by the currently loaded plugins.
/// </summary>
/// <param name="plugins">The list of plugins that will be used as a plugin pool to get provided types.</param>
/// <returns>The list of types available.</returns>
private ICollection<Type> GetProvidedTypes()
private ICollection<Type> GetProvidedTypes(ICollection<IPlugin> plugins)
{
List<Type> available = _plugins.SelectMany(x => x.Provides).ToList();
List<ConditionalProvide> conditionals =_plugins
List<Type> available = plugins.SelectMany(x => x.Provides).ToList();
List<ConditionalProvide> conditionals = plugins
.SelectMany(x => x.ConditionalProvides)
.Where(x => x.Condition.Condition())
.ToList();
@ -199,6 +210,14 @@ namespace Kyoo.Controllers
/// <inheritdoc />
protected override Assembly Load(AssemblyName assemblyName)
{
Assembly existing = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(x =>
{
AssemblyName name = x.GetName();
return name.Name == assemblyName.Name && name.Version == assemblyName.Version;
});
if (existing != null)
return existing;
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
return LoadFromAssemblyPath(assemblyPath);

View File

@ -36,17 +36,11 @@
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
<ProjectReference Include="../Kyoo.CommonAPI/Kyoo.CommonAPI.csproj" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.3" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.12" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="5.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.14" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<ProjectReference Include="..\Kyoo.Postgresql\Kyoo.Postgresql.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -2,6 +2,7 @@ using System;
using System.IO;
using Kyoo.Controllers;
using Kyoo.Models;
using Kyoo.Postgresql;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.AngularCli;
@ -39,12 +40,12 @@ namespace Kyoo
/// </param>
/// <param name="configuration">The configuration context</param>
/// <param name="loggerFactory">A logger factory used to create a logger for the plugin manager.</param>
public Startup(IServiceProvider hostProvider, IConfiguration configuration, ILoggerFactory loggerFactory)
public Startup(IServiceProvider hostProvider, IConfiguration configuration, ILoggerFactory loggerFactory, IWebHostEnvironment host)
{
_configuration = configuration;
_plugins = new PluginManager(hostProvider, _configuration, loggerFactory.CreateLogger<PluginManager>());
_plugins.LoadPlugins(new [] {new CoreModule()});
_plugins.LoadPlugins(new IPlugin[] {new CoreModule(), new PostgresModule(configuration, host)});
}
/// <summary>
@ -132,13 +133,13 @@ namespace Kyoo
});
app.UseResponseCompression();
app.UseSpa(spa =>
{
spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp");
if (env.IsDevelopment())
spa.UseAngularCliServer("start");
});
// app.UseSpa(spa =>
// {
// spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp");
//
// if (env.IsDevelopment())
// spa.UseAngularCliServer("start");
// });
_plugins.ConfigureAspnet(app);