mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Fix services provider issues
This commit is contained in:
parent
9bd1e50de3
commit
436cbee752
@ -1,2 +1,2 @@
|
|||||||
--project
|
--project
|
||||||
src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
src/Kyoo.Core
|
||||||
|
@ -20,6 +20,7 @@ using System;
|
|||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Core.Controllers;
|
using Kyoo.Core.Controllers;
|
||||||
|
using Kyoo.Core.Extensions;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ public static class CoreModule
|
|||||||
where TRepo : class, IRepository<T>
|
where TRepo : class, IRepository<T>
|
||||||
{
|
{
|
||||||
services.AddScoped<TRepo>();
|
services.AddScoped<TRepo>();
|
||||||
services.AddScoped<IRepository<T>>(x => x.GetRequiredService<TRepo>());
|
services.AddScoped<IRepository<T>>(x => x.GetRequiredService<TRepo>()).AllowLazy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ConfigureKyoo(this WebApplicationBuilder builder)
|
public static void ConfigureKyoo(this WebApplicationBuilder builder)
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using AspNetCore.Proxy;
|
using AspNetCore.Proxy;
|
||||||
@ -83,4 +85,52 @@ public static class ServiceExtensions
|
|||||||
services.AddProxies();
|
services.AddProxies();
|
||||||
services.AddHttpClient();
|
services.AddHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stollen from https://stackoverflow.com/questions/44934511/does-net-core-dependency-injection-support-lazyt
|
||||||
|
public static IServiceCollection AllowLazy(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
ServiceDescriptor lastRegistration = services.Last();
|
||||||
|
Type serviceType = lastRegistration.ServiceType;
|
||||||
|
|
||||||
|
// The constructor for Lazy<T> expects a Func<T> which is hard to create dynamically.
|
||||||
|
Type lazyServiceType = typeof(Lazy<>).MakeGenericType(serviceType);
|
||||||
|
|
||||||
|
// Create a typed MethodInfo for `serviceProvider.GetRequiredService<T>`,
|
||||||
|
// where T has been resolved to the required ServiceType
|
||||||
|
System.Reflection.MethodInfo? getRequiredServiceMethod = typeof(ServiceProviderServiceExtensions).GetMethod(
|
||||||
|
nameof(ServiceProviderServiceExtensions.GetRequiredService),
|
||||||
|
1,
|
||||||
|
[typeof(IServiceProvider)]
|
||||||
|
);
|
||||||
|
|
||||||
|
System.Reflection.MethodInfo? getRequiredServiceMethodTyped = getRequiredServiceMethod?.MakeGenericMethod(
|
||||||
|
serviceType
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now create a lambda expression equivalent to:
|
||||||
|
//
|
||||||
|
// serviceProvider => serviceProvider.GetRequiredService<T>();
|
||||||
|
//
|
||||||
|
ParameterExpression parameterExpr = Expression.Parameter(typeof(IServiceProvider), "serviceLocator");
|
||||||
|
LambdaExpression lambda = Expression.Lambda(
|
||||||
|
Expression.Call(null, getRequiredServiceMethodTyped!, parameterExpr),
|
||||||
|
parameterExpr
|
||||||
|
);
|
||||||
|
|
||||||
|
Delegate lambdaCompiled = lambda.Compile();
|
||||||
|
|
||||||
|
services.Add(
|
||||||
|
new ServiceDescriptor(
|
||||||
|
lazyServiceType,
|
||||||
|
serviceProvider =>
|
||||||
|
Activator.CreateInstance(
|
||||||
|
lazyServiceType,
|
||||||
|
lambdaCompiled.DynamicInvoke(serviceProvider)
|
||||||
|
)!,
|
||||||
|
lastRegistration.Lifetime
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<AssemblyName>Kyoo.Core</AssemblyName>
|
<AssemblyName>Kyoo.Core</AssemblyName>
|
||||||
<RootNamespace>Kyoo.Core</RootNamespace>
|
<RootNamespace>Kyoo.Core</RootNamespace>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
<AssemblyName>kyoo</AssemblyName>
|
||||||
<!-- Limit the number of threads, the default is to not limit so scanning the library
|
<!-- Limit the number of threads, the default is to not limit so scanning the library
|
||||||
create way too many of them and slows the whole server. -->
|
create way too many of them and slows the whole server. -->
|
||||||
<ThreadPoolMaxThreads>50</ThreadPoolMaxThreads>
|
<ThreadPoolMaxThreads>50</ThreadPoolMaxThreads>
|
||||||
@ -22,6 +23,10 @@
|
|||||||
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="3.0.1" />
|
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="3.0.1" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.7" />
|
<PackageReference Include="SkiaSharp" Version="2.88.7" />
|
||||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -29,7 +29,6 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Serilog.Templates;
|
using Serilog.Templates;
|
||||||
@ -38,7 +37,7 @@ using Serilog.Templates.Themes;
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
const string EnvironmentName = "Development";
|
const string EnvironmentName = "Development";
|
||||||
#else
|
#else
|
||||||
const string EnvironmentName = "Production";
|
const string EnvironmentName = "Production";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(
|
WebApplicationBuilder builder = WebApplication.CreateBuilder(
|
||||||
@ -72,13 +71,10 @@ AppDomain.CurrentDomain.UnhandledException += (_, ex) =>
|
|||||||
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
|
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
|
||||||
builder.Host.UseSerilog();
|
builder.Host.UseSerilog();
|
||||||
|
|
||||||
|
builder
|
||||||
// Set current directory, used by thumbnails for example.
|
.Services.AddMvcCore()
|
||||||
string path = Path.GetFullPath(builder.Configuration.GetValue("DATADIR", "/kyoo")!);
|
.AddApplicationPart(typeof(CoreModule).Assembly)
|
||||||
if (!Directory.Exists(path))
|
.AddApplicationPart(typeof(AuthenticationModule).Assembly);
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
Environment.CurrentDirectory = path;
|
|
||||||
Log.Information("Data directory: {DataDirectory}", Environment.CurrentDirectory);
|
|
||||||
|
|
||||||
builder.Services.ConfigureMvc();
|
builder.Services.ConfigureMvc();
|
||||||
builder.Services.ConfigureOpenApi();
|
builder.Services.ConfigureOpenApi();
|
||||||
@ -97,6 +93,13 @@ app.UseRouting();
|
|||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
|
// Set current directory, used by thumbnails for example.
|
||||||
|
string path = Path.GetFullPath(builder.Configuration.GetValue("DATADIR", "/kyoo")!);
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
Environment.CurrentDirectory = path;
|
||||||
|
Log.Information("Data directory: {DataDirectory}", Environment.CurrentDirectory);
|
||||||
|
|
||||||
// Activate services that always run in the background
|
// Activate services that always run in the background
|
||||||
app.Services.GetRequiredService<MeiliSync>();
|
app.Services.GetRequiredService<MeiliSync>();
|
||||||
app.Services.GetRequiredService<RabbitProducer>();
|
app.Services.GetRequiredService<RabbitProducer>();
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Meilisearch;
|
using Meilisearch;
|
||||||
@ -151,7 +154,7 @@ public static class MeilisearchModule
|
|||||||
builder.Configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
builder.Configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
builder.Services.AddSingleton<ISearchManager, SearchManager>();
|
builder.Services.AddScoped<ISearchManager, SearchManager>();
|
||||||
builder.Services.AddSingleton<MeiliSync>();
|
builder.Services.AddSingleton<MeiliSync>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,38 +33,15 @@ using Npgsql;
|
|||||||
|
|
||||||
namespace Kyoo.Postgresql;
|
namespace Kyoo.Postgresql;
|
||||||
|
|
||||||
public class PostgresContext : DatabaseContext
|
public class PostgresContext(DbContextOptions options, IHttpContextAccessor accessor)
|
||||||
|
: DatabaseContext(options, accessor)
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Should the configure step be skipped? This is used when the database is created via DbContextOptions.
|
|
||||||
/// </summary>
|
|
||||||
private readonly bool _skipConfigure;
|
|
||||||
|
|
||||||
public PostgresContext(DbContextOptions options, IHttpContextAccessor accessor)
|
|
||||||
: base(options, accessor)
|
|
||||||
{
|
|
||||||
_skipConfigure = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set connection information for this database context
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="optionsBuilder">An option builder to fill.</param>
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
if (!_skipConfigure)
|
|
||||||
{
|
|
||||||
optionsBuilder.UseNpgsql();
|
|
||||||
}
|
|
||||||
|
|
||||||
optionsBuilder.UseSnakeCaseNamingConvention();
|
optionsBuilder.UseSnakeCaseNamingConvention();
|
||||||
base.OnConfiguring(optionsBuilder);
|
base.OnConfiguring(optionsBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set database parameters to support every types of Kyoo.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="modelBuilder">The database's model builder.</param>
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.HasPostgresEnum<Status>();
|
modelBuilder.HasPostgresEnum<Status>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user