using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using FluentMigrator.Runner; using NLog; using Nancy.Bootstrapper; using NzbDrone.Api; using NzbDrone.Common; using NzbDrone.Common.Eventing; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.ExternalNotification; using NzbDrone.Core.Organizer; using NzbDrone.Core.RootFolders; using TinyIoC; namespace NzbDrone { public static class ContainerBuilder { private static readonly Logger Logger = LogManager.GetLogger("ContainerBuilder"); private static readonly List NzbDroneTypes; static ContainerBuilder() { NzbDroneTypes = new List(); NzbDroneTypes.AddRange(Assembly.Load("NzbDrone").GetTypes()); NzbDroneTypes.AddRange(Assembly.Load("NzbDrone.Common").GetTypes()); NzbDroneTypes.AddRange(Assembly.Load("NzbDrone.Core").GetTypes()); NzbDroneTypes.AddRange(Assembly.Load("NzbDrone.Api").GetTypes()); } public static TinyIoCContainer BuildNzbDroneContainer() { var container = new TinyIoCContainer(); container.AutoRegisterInterfaces(); container.AutoRegisterImplementations(); container.Register().AsSingleton(); container.Register().AsSingleton(); container.Register().AsSingleton(); container.Register().AsSingleton(); container.Register(typeof(IBasicRepository), typeof(BasicRepository)).AsMultiInstance(); container.Register(typeof(IBasicRepository), typeof(BasicRepository)).AsMultiInstance(); container.InitDatabase(); ReportingService.RestProvider = container.Resolve(); return container; } private static void InitDatabase(this TinyIoCContainer container) { Logger.Info("Registering Database..."); //TODO: move this to factory var environmentProvider = new EnvironmentProvider(); var appDataPath = environmentProvider.GetAppDataPath(); if (!Directory.Exists(appDataPath)) { Directory.CreateDirectory(appDataPath); } container.Register((c, p) => c.Resolve().Create(environmentProvider.GetNzbDroneDatabase())); } private static void AutoRegisterInterfaces(this TinyIoCContainer container) { var interfaces = NzbDroneTypes.Where(t => t.IsInterface); foreach (var contract in interfaces) { container.AutoRegisterImplementations(contract); } } private static void AutoRegisterImplementations(this TinyIoCContainer container) { container.AutoRegisterImplementations(typeof(TContract)); } private static void AutoRegisterImplementations(this TinyIoCContainer container, Type contractType) { var implementations = GetImplementations(contractType).ToList(); if (implementations.Count == 0) { return; } if (implementations.Count == 1) { container.Register(contractType, implementations.Single()).AsMultiInstance(); } else { container.RegisterMultiple(contractType, implementations).AsMultiInstance(); } } private static IEnumerable GetImplementations(Type contractType) { return NzbDroneTypes .Where(implementation => contractType.IsAssignableFrom(implementation) && !implementation.IsInterface && !implementation.IsAbstract ); } } }