Move to Microsoft.Extensions.DependencyInjection

This PR replaces SimpleInjector with
Microsoft.Extensions.DependencyInjection.
This commit is contained in:
Bond_009 2019-02-03 17:09:12 +01:00 committed by Bond-009
parent eb4b705167
commit 81a8ebde22
9 changed files with 152 additions and 390 deletions

View File

@ -38,7 +38,9 @@ namespace Emby.Dlna
IFileSystem fileSystem, IFileSystem fileSystem,
IApplicationPaths appPaths, IApplicationPaths appPaths,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IAssemblyInfo assemblyInfo) IJsonSerializer jsonSerializer,
IServerApplicationHost appHost,
IAssemblyInfo assemblyInfo)
{ {
_xmlSerializer = xmlSerializer; _xmlSerializer = xmlSerializer;
_fileSystem = fileSystem; _fileSystem = fileSystem;

View File

@ -36,7 +36,8 @@ namespace Emby.Dlna.MediaReceiverRegistrar
}; };
} }
public ControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) : base(config, logger, xmlReaderSettingsFactory) public ControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
: base(config, logger, xmlReaderSettingsFactory)
{ {
} }
} }

View File

@ -105,6 +105,7 @@ using MediaBrowser.Providers.Subtitles;
using MediaBrowser.WebDashboard.Api; using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers; using MediaBrowser.XbmcMetadata.Providers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using ServiceStack; using ServiceStack;
using ServiceStack.Text.Jsv; using ServiceStack.Text.Jsv;
using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate; using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate;
@ -202,7 +203,7 @@ namespace Emby.Server.Implementations
/// Gets all concrete types. /// Gets all concrete types.
/// </summary> /// </summary>
/// <value>All concrete types.</value> /// <value>All concrete types.</value>
public Tuple<Type, string>[] AllConcreteTypes { get; protected set; } public Type[] AllConcreteTypes { get; protected set; }
/// <summary> /// <summary>
/// The disposable parts /// The disposable parts
@ -219,8 +220,6 @@ namespace Emby.Server.Implementations
protected IEnvironmentInfo EnvironmentInfo { get; set; } protected IEnvironmentInfo EnvironmentInfo { get; set; }
private IBlurayExaminer BlurayExaminer { get; set; }
public PackageVersionClass SystemUpdateLevel public PackageVersionClass SystemUpdateLevel
{ {
get get
@ -232,12 +231,7 @@ namespace Emby.Server.Implementations
} }
} }
public virtual string OperatingSystemDisplayName => EnvironmentInfo.OperatingSystemName; protected IServiceProvider _serviceProvider;
/// <summary>
/// The container
/// </summary>
protected readonly SimpleInjector.Container Container = new SimpleInjector.Container();
/// <summary> /// <summary>
/// Gets the server configuration manager. /// Gets the server configuration manager.
@ -453,138 +447,58 @@ namespace Emby.Server.Implementations
/// <value>The name.</value> /// <value>The name.</value>
public string Name => ApplicationProductName; public string Name => ApplicationProductName;
private static Tuple<Assembly, string> GetAssembly(Type type)
{
var assembly = type.GetTypeInfo().Assembly;
return new Tuple<Assembly, string>(assembly, null);
}
public virtual IStreamHelper CreateStreamHelper()
{
return new StreamHelper();
}
/// <summary> /// <summary>
/// Creates an instance of type and resolves all constructor dependancies /// Creates an instance of type and resolves all constructor dependencies
/// </summary> /// </summary>
/// <param name="type">The type.</param> /// <param name="type">The type.</param>
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public object CreateInstance(Type type) public object CreateInstance(Type type)
{ => ActivatorUtilities.CreateInstance(_serviceProvider, type);
return Container.GetInstance(type);
} /// <summary>
/// Creates an instance of type and resolves all constructor dependencies
/// </summary>
/// <param name="type">The type.</param>
/// <returns>System.Object.</returns>
public T CreateInstance<T>()
=> ActivatorUtilities.CreateInstance<T>(_serviceProvider);
/// <summary> /// <summary>
/// Creates the instance safe. /// Creates the instance safe.
/// </summary> /// </summary>
/// <param name="typeInfo">The type information.</param> /// <param name="typeInfo">The type information.</param>
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
protected object CreateInstanceSafe(Tuple<Type, string> typeInfo) protected object CreateInstanceSafe(Type type)
{ {
var type = typeInfo.Item1;
try try
{ {
return Container.GetInstance(type); return ActivatorUtilities.CreateInstance(_serviceProvider, type);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogError(ex, "Error creating {type}", type.FullName); Logger.LogError(ex, "Error creating {Type}", type);
// Don't blow up in release mode // Don't blow up in release mode
return null; return null;
} }
} }
/// <summary>
/// Registers the specified obj.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj">The obj.</param>
/// <param name="manageLifetime">if set to <c>true</c> [manage lifetime].</param>
protected void RegisterSingleInstance<T>(T obj, bool manageLifetime = true)
where T : class
{
Container.RegisterInstance<T>(obj);
if (manageLifetime)
{
var disposable = obj as IDisposable;
if (disposable != null)
{
DisposableParts.Add(disposable);
}
}
}
/// <summary>
/// Registers the single instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func">The func.</param>
protected void RegisterSingleInstance<T>(Func<T> func)
where T : class
{
Container.RegisterSingleton(func);
}
/// <summary> /// <summary>
/// Resolves this instance. /// Resolves this instance.
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns>``0.</returns> /// <returns>``0.</returns>
public T Resolve<T>() public T Resolve<T>() => _serviceProvider.GetService<T>();
{
return (T)Container.GetRegistration(typeof(T), true).GetInstance();
}
/// <summary>
/// Resolves this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>``0.</returns>
public T TryResolve<T>()
{
var result = Container.GetRegistration(typeof(T), false);
if (result == null)
{
return default(T);
}
return (T)result.GetInstance();
}
/// <summary>
/// Loads the assembly.
/// </summary>
/// <param name="file">The file.</param>
/// <returns>Assembly.</returns>
protected Tuple<Assembly, string> LoadAssembly(string file)
{
try
{
var assembly = Assembly.Load(File.ReadAllBytes(file));
return new Tuple<Assembly, string>(assembly, file);
}
catch (Exception ex)
{
Logger.LogError(ex, "Error loading assembly {File}", file);
return null;
}
}
/// <summary> /// <summary>
/// Gets the export types. /// Gets the export types.
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns>IEnumerable{Type}.</returns> /// <returns>IEnumerable{Type}.</returns>
public IEnumerable<Tuple<Type, string>> GetExportTypes<T>() public IEnumerable<Type> GetExportTypes<T>()
{ {
var currentType = typeof(T); var currentType = typeof(T);
return AllConcreteTypes.Where(i => currentType.IsAssignableFrom(i.Item1)); return AllConcreteTypes.Where(i => currentType.IsAssignableFrom(i));
} }
/// <summary> /// <summary>
@ -596,7 +510,7 @@ namespace Emby.Server.Implementations
public IEnumerable<T> GetExports<T>(bool manageLifetime = true) public IEnumerable<T> GetExports<T>(bool manageLifetime = true)
{ {
var parts = GetExportTypes<T>() var parts = GetExportTypes<T>()
.Select(CreateInstanceSafe) .Select(x => CreateInstanceSafe(x))
.Where(i => i != null) .Where(i => i != null)
.Cast<T>(); .Cast<T>();
@ -611,20 +525,16 @@ namespace Emby.Server.Implementations
return parts; return parts;
} }
public List<Tuple<T, string>> GetExportsWithInfo<T>(bool manageLifetime = true) public List<(T, string)> GetExportsWithInfo<T>(bool manageLifetime = true)
{ {
var parts = GetExportTypes<T>() var parts = GetExportTypes<T>()
.Select(i => .Select(i =>
{ {
var obj = CreateInstanceSafe(i); var obj = CreateInstanceSafe(i);
if (obj == null) return ((T)obj, i.Assembly.Location);
{
return null;
}
return new Tuple<T, string>((T)obj, i.Item2);
}) })
.Where(i => i != null) .Where(i => i.Item1 != null)
.ToList(); .ToList();
if (manageLifetime) if (manageLifetime)
@ -691,7 +601,7 @@ namespace Emby.Server.Implementations
} }
} }
public async Task Init() public async Task Init(IServiceCollection serviceCollection)
{ {
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
@ -721,7 +631,7 @@ namespace Emby.Server.Implementations
SetHttpLimit(); SetHttpLimit();
await RegisterResources(); await RegisterResources(serviceCollection);
FindParts(); FindParts();
} }
@ -736,104 +646,104 @@ namespace Emby.Server.Implementations
/// <summary> /// <summary>
/// Registers resources that classes will depend on /// Registers resources that classes will depend on
/// </summary> /// </summary>
protected async Task RegisterResources() protected async Task RegisterResources(IServiceCollection serviceCollection)
{ {
RegisterSingleInstance(ConfigurationManager); serviceCollection.AddSingleton(ConfigurationManager);
RegisterSingleInstance<IApplicationHost>(this); serviceCollection.AddSingleton<IApplicationHost>(this);
RegisterSingleInstance<IApplicationPaths>(ApplicationPaths); serviceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
RegisterSingleInstance(JsonSerializer);
RegisterSingleInstance(LoggerFactory, false); serviceCollection.AddSingleton(JsonSerializer);
RegisterSingleInstance(Logger);
RegisterSingleInstance(EnvironmentInfo); serviceCollection.AddSingleton(LoggerFactory);
serviceCollection.AddLogging();
serviceCollection.AddSingleton(Logger);
RegisterSingleInstance(FileSystemManager); serviceCollection.AddSingleton(EnvironmentInfo);
serviceCollection.AddSingleton(FileSystemManager);
HttpClient = CreateHttpClient(); HttpClient = CreateHttpClient();
RegisterSingleInstance(HttpClient); serviceCollection.AddSingleton(HttpClient);
RegisterSingleInstance(NetworkManager); serviceCollection.AddSingleton(NetworkManager);
IsoManager = new IsoManager(); IsoManager = new IsoManager();
RegisterSingleInstance(IsoManager); serviceCollection.AddSingleton(IsoManager);
TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LoggerFactory, FileSystemManager); TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LoggerFactory, FileSystemManager);
RegisterSingleInstance(TaskManager); serviceCollection.AddSingleton(TaskManager);
RegisterSingleInstance(XmlSerializer); serviceCollection.AddSingleton(XmlSerializer);
ProcessFactory = new ProcessFactory(); ProcessFactory = new ProcessFactory();
RegisterSingleInstance(ProcessFactory); serviceCollection.AddSingleton(ProcessFactory);
var streamHelper = CreateStreamHelper(); ApplicationHost.StreamHelper = new StreamHelper();
ApplicationHost.StreamHelper = streamHelper; serviceCollection.AddSingleton(StreamHelper);
RegisterSingleInstance(streamHelper);
RegisterSingleInstance(CryptographyProvider); serviceCollection.AddSingleton(CryptographyProvider);
SocketFactory = new SocketFactory(); SocketFactory = new SocketFactory();
RegisterSingleInstance(SocketFactory); serviceCollection.AddSingleton(SocketFactory);
InstallationManager = new InstallationManager(LoggerFactory, this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime); InstallationManager = new InstallationManager(LoggerFactory, this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime);
RegisterSingleInstance(InstallationManager); serviceCollection.AddSingleton(InstallationManager);
ZipClient = new ZipClient(FileSystemManager); ZipClient = new ZipClient(FileSystemManager);
RegisterSingleInstance(ZipClient); serviceCollection.AddSingleton(ZipClient);
HttpResultFactory = new HttpResultFactory(LoggerFactory, FileSystemManager, JsonSerializer, CreateBrotliCompressor()); HttpResultFactory = new HttpResultFactory(LoggerFactory, FileSystemManager, JsonSerializer, CreateBrotliCompressor());
RegisterSingleInstance(HttpResultFactory); serviceCollection.AddSingleton(HttpResultFactory);
RegisterSingleInstance<IServerApplicationHost>(this); serviceCollection.AddSingleton<IServerApplicationHost>(this);
RegisterSingleInstance<IServerApplicationPaths>(ApplicationPaths); serviceCollection.AddSingleton<IServerApplicationPaths>(ApplicationPaths);
RegisterSingleInstance(ServerConfigurationManager); serviceCollection.AddSingleton(ServerConfigurationManager);
IAssemblyInfo assemblyInfo = new AssemblyInfo(); var assemblyInfo = new AssemblyInfo();
RegisterSingleInstance(assemblyInfo); serviceCollection.AddSingleton<IAssemblyInfo>(assemblyInfo);
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory); LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory);
await LocalizationManager.LoadAll(); await LocalizationManager.LoadAll();
RegisterSingleInstance<ILocalizationManager>(LocalizationManager); serviceCollection.AddSingleton<ILocalizationManager>(LocalizationManager);
BlurayExaminer = new BdInfoExaminer(FileSystemManager); serviceCollection.AddSingleton<IBlurayExaminer>(new BdInfoExaminer(FileSystemManager));
RegisterSingleInstance(BlurayExaminer);
RegisterSingleInstance<IXmlReaderSettingsFactory>(new XmlReaderSettingsFactory()); serviceCollection.AddSingleton<IXmlReaderSettingsFactory>(new XmlReaderSettingsFactory());
UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager); UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager);
RegisterSingleInstance(UserDataManager); serviceCollection.AddSingleton(UserDataManager);
UserRepository = GetUserRepository(); UserRepository = GetUserRepository();
// This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
RegisterSingleInstance(UserRepository); serviceCollection.AddSingleton(UserRepository);
var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LoggerFactory, JsonSerializer, ApplicationPaths, FileSystemManager); var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LoggerFactory, JsonSerializer, ApplicationPaths, FileSystemManager);
DisplayPreferencesRepository = displayPreferencesRepo; DisplayPreferencesRepository = displayPreferencesRepo;
RegisterSingleInstance(DisplayPreferencesRepository); serviceCollection.AddSingleton(DisplayPreferencesRepository);
ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, JsonSerializer, LoggerFactory, assemblyInfo); ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, JsonSerializer, LoggerFactory, assemblyInfo);
RegisterSingleInstance<IItemRepository>(ItemRepository); serviceCollection.AddSingleton<IItemRepository>(ItemRepository);
AuthenticationRepository = GetAuthenticationRepository(); AuthenticationRepository = GetAuthenticationRepository();
RegisterSingleInstance(AuthenticationRepository); serviceCollection.AddSingleton(AuthenticationRepository);
UserManager = new UserManager(LoggerFactory, ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, this, JsonSerializer, FileSystemManager, CryptographyProvider); UserManager = new UserManager(LoggerFactory, ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, this, JsonSerializer, FileSystemManager, CryptographyProvider);
RegisterSingleInstance(UserManager); serviceCollection.AddSingleton(UserManager);
LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager); LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
RegisterSingleInstance(LibraryManager); serviceCollection.AddSingleton(LibraryManager);
// TODO wtaylor: investigate use of second music manager // TODO wtaylor: investigate use of second music manager
var musicManager = new MusicManager(LibraryManager); var musicManager = new MusicManager(LibraryManager);
RegisterSingleInstance<IMusicManager>(new MusicManager(LibraryManager)); serviceCollection.AddSingleton<IMusicManager>(new MusicManager(LibraryManager));
LibraryMonitor = new LibraryMonitor(LoggerFactory, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, EnvironmentInfo); LibraryMonitor = new LibraryMonitor(LoggerFactory, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, EnvironmentInfo);
RegisterSingleInstance(LibraryMonitor); serviceCollection.AddSingleton(LibraryMonitor);
RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LoggerFactory, LibraryManager, UserManager)); serviceCollection.AddSingleton<ISearchEngine>(new SearchEngine(LoggerFactory, LibraryManager, UserManager));
CertificateInfo = GetCertificateInfo(true); CertificateInfo = GetCertificateInfo(true);
Certificate = GetCertificate(CertificateInfo); Certificate = GetCertificate(CertificateInfo);
@ -848,81 +758,80 @@ namespace Emby.Server.Implementations
GetParseFn); GetParseFn);
HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
RegisterSingleInstance(HttpServer); serviceCollection.AddSingleton(HttpServer);
ImageProcessor = GetImageProcessor(); ImageProcessor = GetImageProcessor();
RegisterSingleInstance(ImageProcessor); serviceCollection.AddSingleton(ImageProcessor);
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager); TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
RegisterSingleInstance(TVSeriesManager); serviceCollection.AddSingleton(TVSeriesManager);
var encryptionManager = new EncryptionManager(); var encryptionManager = new EncryptionManager();
RegisterSingleInstance<IEncryptionManager>(encryptionManager); serviceCollection.AddSingleton<IEncryptionManager>(encryptionManager);
DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LoggerFactory, NetworkManager); DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LoggerFactory, NetworkManager);
RegisterSingleInstance(DeviceManager); serviceCollection.AddSingleton(DeviceManager);
MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder); MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder);
RegisterSingleInstance(MediaSourceManager); serviceCollection.AddSingleton(MediaSourceManager);
SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager); SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager);
RegisterSingleInstance(SubtitleManager); serviceCollection.AddSingleton(SubtitleManager);
ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer); ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer);
RegisterSingleInstance(ProviderManager); serviceCollection.AddSingleton(ProviderManager);
DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager); DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager);
RegisterSingleInstance(DtoService); serviceCollection.AddSingleton(DtoService);
ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager); ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager);
RegisterSingleInstance(ChannelManager); serviceCollection.AddSingleton(ChannelManager);
SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager);
RegisterSingleInstance(SessionManager); serviceCollection.AddSingleton(SessionManager);
var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo); serviceCollection.AddSingleton<IDlnaManager>(new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo));
RegisterSingleInstance<IDlnaManager>(dlnaManager);
CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager); CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager);
RegisterSingleInstance(CollectionManager); serviceCollection.AddSingleton(CollectionManager);
PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LoggerFactory, UserManager, ProviderManager); PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LoggerFactory, UserManager, ProviderManager);
RegisterSingleInstance(PlaylistManager); serviceCollection.AddSingleton(PlaylistManager);
LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager); LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager);
RegisterSingleInstance(LiveTvManager); serviceCollection.AddSingleton(LiveTvManager);
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
RegisterSingleInstance(UserViewManager); serviceCollection.AddSingleton(UserViewManager);
NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager); NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager);
RegisterSingleInstance(NotificationManager); serviceCollection.AddSingleton(NotificationManager);
RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory)); serviceCollection.AddSingleton<IDeviceDiscovery>(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory));
ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository); ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
RegisterSingleInstance(ChapterManager); serviceCollection.AddSingleton(ChapterManager);
RegisterMediaEncoder(assemblyInfo); RegisterMediaEncoder(serviceCollection);
EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager); EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
RegisterSingleInstance(EncodingManager); serviceCollection.AddSingleton(EncodingManager);
var activityLogRepo = GetActivityLogRepository(); var activityLogRepo = GetActivityLogRepository();
RegisterSingleInstance(activityLogRepo); serviceCollection.AddSingleton(activityLogRepo);
RegisterSingleInstance<IActivityManager>(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(LoggerFactory, activityLogRepo, UserManager));
var authContext = new AuthorizationContext(AuthenticationRepository, UserManager); var authContext = new AuthorizationContext(AuthenticationRepository, UserManager);
RegisterSingleInstance<IAuthorizationContext>(authContext); serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager)); serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, SessionManager, NetworkManager); AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, SessionManager, NetworkManager);
RegisterSingleInstance(AuthService); serviceCollection.AddSingleton(AuthService);
SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory); SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory);
RegisterSingleInstance(SubtitleEncoder); serviceCollection.AddSingleton(SubtitleEncoder);
RegisterSingleInstance(CreateResourceFileManager()); serviceCollection.AddSingleton(CreateResourceFileManager());
displayPreferencesRepo.Initialize(); displayPreferencesRepo.Initialize();
@ -935,6 +844,8 @@ namespace Emby.Server.Implementations
((UserDataManager)UserDataManager).Repository = userDataRepo; ((UserDataManager)UserDataManager).Repository = userDataRepo;
ItemRepository.Initialize(userDataRepo, UserManager); ItemRepository.Initialize(userDataRepo, UserManager);
((LibraryManager)LibraryManager).ItemRepository = ItemRepository; ((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
_serviceProvider = serviceCollection.BuildServiceProvider();
} }
protected virtual IBrotliCompressor CreateBrotliCompressor() protected virtual IBrotliCompressor CreateBrotliCompressor()
@ -1066,7 +977,7 @@ namespace Emby.Server.Implementations
/// Registers the media encoder. /// Registers the media encoder.
/// </summary> /// </summary>
/// <returns>Task.</returns> /// <returns>Task.</returns>
private void RegisterMediaEncoder(IAssemblyInfo assemblyInfo) private void RegisterMediaEncoder(IServiceCollection serviceCollection)
{ {
string encoderPath = null; string encoderPath = null;
string probePath = null; string probePath = null;
@ -1098,7 +1009,7 @@ namespace Emby.Server.Implementations
5000); 5000);
MediaEncoder = mediaEncoder; MediaEncoder = mediaEncoder;
RegisterSingleInstance(MediaEncoder); serviceCollection.AddSingleton(MediaEncoder);
} }
/// <summary> /// <summary>
@ -1208,7 +1119,7 @@ namespace Emby.Server.Implementations
IsoManager.AddParts(GetExports<IIsoMounter>()); IsoManager.AddParts(GetExports<IIsoMounter>());
} }
private IPlugin LoadPlugin(Tuple<IPlugin, string> info) private IPlugin LoadPlugin((IPlugin, string) info)
{ {
var plugin = info.Item1; var plugin = info.Item1;
var assemblyFilePath = info.Item2; var assemblyFilePath = info.Item2;
@ -1264,78 +1175,15 @@ namespace Emby.Server.Implementations
{ {
Logger.LogInformation("Loading assemblies"); Logger.LogInformation("Loading assemblies");
var assemblyInfos = GetComposablePartAssemblies(); AllConcreteTypes = GetComposablePartAssemblies()
.SelectMany(x => x.ExportedTypes)
foreach (var assemblyInfo in assemblyInfos) .Where(type =>
{
var assembly = assemblyInfo.Item1;
var path = assemblyInfo.Item2;
if (path == null)
{ {
Logger.LogInformation("Loading {assemblyName}", assembly.FullName); return type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType;
}
else
{
Logger.LogInformation("Loading {assemblyName} from {path}", assembly.FullName, path);
}
}
AllConcreteTypes = assemblyInfos
.SelectMany(GetTypes)
.Where(info =>
{
var t = info.Item1;
return t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType;
}) })
.ToArray(); .ToArray();
} }
/// <summary>
/// Gets a list of types within an assembly
/// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
/// </summary>
protected List<Tuple<Type, string>> GetTypes(Tuple<Assembly, string> assemblyInfo)
{
if (assemblyInfo == null)
{
return new List<Tuple<Type, string>>();
}
var assembly = assemblyInfo.Item1;
try
{
// This null checking really shouldn't be needed but adding it due to some
// unhandled exceptions in mono 5.0 that are a little hard to hunt down
var types = assembly.GetTypes() ?? new Type[] { };
return types.Where(t => t != null).Select(i => new Tuple<Type, string>(i, assemblyInfo.Item2)).ToList();
}
catch (ReflectionTypeLoadException ex)
{
if (ex.LoaderExceptions != null)
{
foreach (var loaderException in ex.LoaderExceptions)
{
if (loaderException != null)
{
Logger.LogError("LoaderException: " + loaderException.Message);
}
}
}
// If it fails we can still get a list of the Types it was able to resolve
var types = ex.Types ?? new Type[] { };
return types.Where(t => t != null).Select(i => new Tuple<Type, string>(i, assemblyInfo.Item2)).ToList();
}
catch (Exception ex)
{
Logger.LogError(ex, "Error loading types from assembly");
return new List<Tuple<Type, string>>();
}
}
private CertificateInfo CertificateInfo { get; set; } private CertificateInfo CertificateInfo { get; set; }
protected X509Certificate Certificate { get; private set; } protected X509Certificate Certificate { get; private set; }
@ -1546,151 +1394,67 @@ namespace Emby.Server.Implementations
/// Gets the composable part assemblies. /// Gets the composable part assemblies.
/// </summary> /// </summary>
/// <returns>IEnumerable{Assembly}.</returns> /// <returns>IEnumerable{Assembly}.</returns>
protected List<Tuple<Assembly, string>> GetComposablePartAssemblies() protected IEnumerable<Assembly> GetComposablePartAssemblies()
{ {
var list = GetPluginAssemblies(ApplicationPaths.PluginsPath); if (Directory.Exists(ApplicationPaths.PluginsPath))
{
foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly))
{
Logger.LogInformation("Loading assembly {Path}", file);
yield return Assembly.LoadFile(file);
}
}
// Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
// This will prevent the .dll file from getting locked, and allow us to replace it when needed // This will prevent the .dll file from getting locked, and allow us to replace it when needed
// Include composable parts in the Api assembly // Include composable parts in the Api assembly
list.Add(GetAssembly(typeof(ApiEntryPoint))); yield return typeof(ApiEntryPoint).Assembly;
// Include composable parts in the Dashboard assembly // Include composable parts in the Dashboard assembly
list.Add(GetAssembly(typeof(DashboardService))); yield return typeof(DashboardService).Assembly;
// Include composable parts in the Model assembly // Include composable parts in the Model assembly
list.Add(GetAssembly(typeof(SystemInfo))); yield return typeof(SystemInfo).Assembly;
// Include composable parts in the Common assembly // Include composable parts in the Common assembly
list.Add(GetAssembly(typeof(IApplicationHost))); yield return typeof(IApplicationHost).Assembly;
// Include composable parts in the Controller assembly // Include composable parts in the Controller assembly
list.Add(GetAssembly(typeof(IServerApplicationHost))); yield return typeof(IServerApplicationHost).Assembly;
// Include composable parts in the Providers assembly // Include composable parts in the Providers assembly
list.Add(GetAssembly(typeof(ProviderUtils))); yield return typeof(ProviderUtils).Assembly;
// Include composable parts in the Photos assembly // Include composable parts in the Photos assembly
list.Add(GetAssembly(typeof(PhotoProvider))); yield return typeof(PhotoProvider).Assembly;
// Emby.Server implementations // Emby.Server implementations
list.Add(GetAssembly(typeof(InstallationManager))); yield return typeof(InstallationManager).Assembly;
// MediaEncoding // MediaEncoding
list.Add(GetAssembly(typeof(MediaBrowser.MediaEncoding.Encoder.MediaEncoder))); yield return typeof(MediaBrowser.MediaEncoding.Encoder.MediaEncoder).Assembly;
// Dlna // Dlna
list.Add(GetAssembly(typeof(DlnaEntryPoint))); yield return typeof(DlnaEntryPoint).Assembly;
// Local metadata // Local metadata
list.Add(GetAssembly(typeof(BoxSetXmlSaver))); yield return typeof(BoxSetXmlSaver).Assembly;
// Notifications // Notifications
list.Add(GetAssembly(typeof(NotificationManager))); yield return typeof(NotificationManager).Assembly;
// Xbmc // Xbmc
list.Add(GetAssembly(typeof(ArtistNfoProvider))); yield return typeof(ArtistNfoProvider).Assembly;
list.AddRange(GetAssembliesWithPartsInternal().Select(i => new Tuple<Assembly, string>(i, null))); foreach (var i in GetAssembliesWithPartsInternal())
{
return list.ToList(); yield return i;
}
} }
protected abstract IEnumerable<Assembly> GetAssembliesWithPartsInternal(); protected abstract IEnumerable<Assembly> GetAssembliesWithPartsInternal();
private List<Tuple<Assembly, string>> GetPluginAssemblies(string path)
{
try
{
return FilterAssembliesToLoad(Directory.EnumerateFiles(path, "*.dll", SearchOption.TopDirectoryOnly))
.Select(LoadAssembly)
.Where(a => a != null)
.ToList();
}
catch (DirectoryNotFoundException)
{
return new List<Tuple<Assembly, string>>();
}
}
private IEnumerable<string> FilterAssembliesToLoad(IEnumerable<string> paths)
{
var exclude = new[]
{
"mbplus.dll",
"mbintros.dll",
"embytv.dll",
"Messenger.dll",
"Messages.dll",
"MediaBrowser.Plugins.TvMazeProvider.dll",
"MBBookshelf.dll",
"MediaBrowser.Channels.Adult.YouJizz.dll",
"MediaBrowser.Channels.Vine-co.dll",
"MediaBrowser.Plugins.Vimeo.dll",
"MediaBrowser.Channels.Vevo.dll",
"MediaBrowser.Plugins.Twitch.dll",
"MediaBrowser.Channels.SvtPlay.dll",
"MediaBrowser.Plugins.SoundCloud.dll",
"MediaBrowser.Plugins.SnesBox.dll",
"MediaBrowser.Plugins.RottenTomatoes.dll",
"MediaBrowser.Plugins.Revision3.dll",
"MediaBrowser.Plugins.NesBox.dll",
"MBChapters.dll",
"MediaBrowser.Channels.LeagueOfLegends.dll",
"MediaBrowser.Plugins.ADEProvider.dll",
"MediaBrowser.Channels.BallStreams.dll",
"MediaBrowser.Channels.Adult.Beeg.dll",
"ChannelDownloader.dll",
"Hamstercat.Emby.EmbyBands.dll",
"EmbyTV.dll",
"MediaBrowser.Channels.HitboxTV.dll",
"MediaBrowser.Channels.HockeyStreams.dll",
"MediaBrowser.Plugins.ITV.dll",
"MediaBrowser.Plugins.Lastfm.dll",
"ServerRestart.dll",
"MediaBrowser.Plugins.NotifyMyAndroidNotifications.dll",
"MetadataViewer.dll"
};
var minRequiredVersions = new Dictionary<string, Version>(StringComparer.OrdinalIgnoreCase)
{
{ "moviethemesongs.dll", new Version(1, 6) },
{ "themesongs.dll", new Version(1, 2) }
};
return paths.Where(path =>
{
var filename = Path.GetFileName(path);
if (exclude.Contains(filename ?? string.Empty, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if (minRequiredVersions.TryGetValue(filename, out Version minRequiredVersion))
{
try
{
var version = Version.Parse(FileVersionInfo.GetVersionInfo(path).FileVersion);
if (version < minRequiredVersion)
{
Logger.LogInformation("Not loading {filename} {version} because the minimum supported version is {minRequiredVersion}. Please update to the newer version", filename, version, minRequiredVersion);
return false;
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error getting version number from {path}", path);
return false;
}
}
return true;
});
}
/// <summary> /// <summary>
/// Gets the system status. /// Gets the system status.
/// </summary> /// </summary>
@ -1718,7 +1482,7 @@ namespace Emby.Server.Implementations
SupportsHttps = SupportsHttps, SupportsHttps = SupportsHttps,
HttpsPortNumber = HttpsPort, HttpsPortNumber = HttpsPort,
OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(), OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(),
OperatingSystemDisplayName = OperatingSystemDisplayName, OperatingSystemDisplayName = EnvironmentInfo.OperatingSystemName,
CanSelfRestart = CanSelfRestart, CanSelfRestart = CanSelfRestart,
CanSelfUpdate = CanSelfUpdate, CanSelfUpdate = CanSelfUpdate,
CanLaunchWebBrowser = CanLaunchWebBrowser, CanLaunchWebBrowser = CanLaunchWebBrowser,
@ -1788,7 +1552,7 @@ namespace Emby.Server.Implementations
public async Task<string> GetWanApiUrl(CancellationToken cancellationToken) public async Task<string> GetWanApiUrl(CancellationToken cancellationToken)
{ {
var url = "http://ipv4.icanhazip.com"; const string url = "http://ipv4.icanhazip.com";
try try
{ {
using (var response = await HttpClient.Get(new HttpRequestOptions using (var response = await HttpClient.Get(new HttpRequestOptions

View File

@ -22,9 +22,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" /> <PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
<PackageReference Include="sharpcompress" Version="0.22.0" /> <PackageReference Include="sharpcompress" Version="0.22.0" />
<PackageReference Include="SimpleInjector" Version="4.4.2" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="1.0.0" /> <PackageReference Include="SQLitePCL.pretty.netstandard" Version="1.0.0" />
<PackageReference Include="UTF.Unknown" Version="1.0.0-beta1" /> <PackageReference Include="UTF.Unknown" Version="1.0.0-beta1" />
</ItemGroup> </ItemGroup>

View File

@ -21,6 +21,7 @@ using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Serilog; using Serilog;
using Serilog.AspNetCore; using Serilog.AspNetCore;
@ -114,7 +115,7 @@ namespace Jellyfin.Server
new NullImageEncoder(), new NullImageEncoder(),
new NetworkManager(_loggerFactory, environmentInfo))) new NetworkManager(_loggerFactory, environmentInfo)))
{ {
await appHost.Init(); await appHost.Init(new ServiceCollection());
appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);

View File

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Events; using MediaBrowser.Model.Events;
using MediaBrowser.Model.Updates; using MediaBrowser.Model.Updates;
using Microsoft.Extensions.DependencyInjection;
namespace MediaBrowser.Common namespace MediaBrowser.Common
{ {
@ -13,12 +14,6 @@ namespace MediaBrowser.Common
/// </summary> /// </summary>
public interface IApplicationHost public interface IApplicationHost
{ {
/// <summary>
/// Gets the display name of the operating system.
/// </summary>
/// <value>The display name of the operating system.</value>
string OperatingSystemDisplayName { get; }
/// <summary> /// <summary>
/// Gets the name. /// Gets the name.
/// </summary> /// </summary>
@ -104,13 +99,6 @@ namespace MediaBrowser.Common
/// <returns>``0.</returns> /// <returns>``0.</returns>
T Resolve<T>(); T Resolve<T>();
/// <summary>
/// Resolves this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>``0.</returns>
T TryResolve<T>();
/// <summary> /// <summary>
/// Shuts down. /// Shuts down.
/// </summary> /// </summary>
@ -131,7 +119,7 @@ namespace MediaBrowser.Common
/// <summary> /// <summary>
/// Inits this instance. /// Inits this instance.
/// </summary> /// </summary>
Task Init(); Task Init(IServiceCollection serviceCollection);
/// <summary> /// <summary>
/// Creates the instance. /// Creates the instance.

View File

@ -11,6 +11,10 @@
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" /> <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\SharedVersion.cs" /> <Compile Include="..\SharedVersion.cs" />
</ItemGroup> </ItemGroup>

View File

@ -24,12 +24,12 @@ namespace MediaBrowser.Model.System
/// Gets or sets the server version. /// Gets or sets the server version.
/// </summary> /// </summary>
/// <value>The version.</value> /// <value>The version.</value>
public string Version { get; set; } public string Version { get; set; }
/// <summary> /// <summary>
/// Gets or sets the operating sytem. /// Gets or sets the operating system.
/// </summary> /// </summary>
/// <value>The operating sytem.</value> /// <value>The operating system.</value>
public string OperatingSystem { get; set; } public string OperatingSystem { get; set; }
/// <summary> /// <summary>

View File

@ -1,3 +1,4 @@
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using MediaBrowser.Model.Updates; using MediaBrowser.Model.Updates;
@ -136,7 +137,7 @@ namespace MediaBrowser.Model.System
/// </summary> /// </summary>
public SystemInfo() public SystemInfo()
{ {
CompletedInstallations = new InstallationInfo[] { }; CompletedInstallations = Array.Empty<InstallationInfo>();
} }
} }
} }