using System.IO.Abstractions; using System.Reflection; using Autofac; using Autofac.Core.Activators.Reflection; using Autofac.Extras.Ordering; using CliFx; using CliFx.Infrastructure; using Common; using Recyclarr.Command.Helpers; using Recyclarr.Config; using Recyclarr.Migration; using Serilog; using Serilog.Core; using TrashLib.Cache; using TrashLib.Config; using TrashLib.Radarr; using TrashLib.Radarr.Config; using TrashLib.Repo; using TrashLib.Sonarr; using TrashLib.Startup; using VersionControl; using YamlDotNet.Serialization; namespace Recyclarr; public static class CompositionRoot { private static void SetupLogging(ContainerBuilder builder) { builder.RegisterType().As(); builder.RegisterType().SingleInstance(); builder.Register(c => { var logPath = Path.Combine(AppPaths.LogDirectory, $"trash_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log"); const string consoleTemplate = "[{Level:u3}] {Message:lj}{NewLine}{Exception}"; return new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console(outputTemplate: consoleTemplate, levelSwitch: c.Resolve()) .WriteTo.File(logPath) .CreateLogger(); }) .As() .SingleInstance(); } private static void ConfigurationRegistrations(ContainerBuilder builder) { builder.RegisterModule(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterGeneric(typeof(ConfigurationLoader<>)) .WithProperty(new AutowiringParameter()) .As(typeof(IConfigurationLoader<>)); } private static void CommandRegistrations(ContainerBuilder builder) { // Register all types deriving from CliFx's ICommand. These are all of our supported subcommands. builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => t.IsAssignableTo(typeof(ICommand))); // Used to access the chosen command class. This is assigned from CliTypeActivator // // note: Do not allow consumers to resolve IServiceConfiguration directly; if this gets cached they end up using // the wrong configuration when multiple instances are used. builder.RegisterType() .As() .SingleInstance(); } public static IContainer Setup() { return Setup(new ContainerBuilder()); } public static IContainer Setup(ContainerBuilder builder) { // Needed for Autofac.Extras.Ordering builder.RegisterSource(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); builder.RegisterModule(); builder.RegisterType().As(); builder.RegisterType().As(); ConfigurationRegistrations(builder); CommandRegistrations(builder); SetupLogging(builder); builder.RegisterModule(); builder.RegisterModule(); builder.RegisterModule(); builder.RegisterModule(); builder.Register(_ => AutoMapperConfig.Setup()).SingleInstance(); return builder.Build(); } }