diff options
Diffstat (limited to 'MediaBrowser.Common/Kernel/BaseKernel.cs')
| -rw-r--r-- | MediaBrowser.Common/Kernel/BaseKernel.cs | 191 |
1 files changed, 114 insertions, 77 deletions
diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs index 2b3986408..2b9550496 100644 --- a/MediaBrowser.Common/Kernel/BaseKernel.cs +++ b/MediaBrowser.Common/Kernel/BaseKernel.cs @@ -1,7 +1,5 @@ using MediaBrowser.Common.Events; using MediaBrowser.Common.IO; -using MediaBrowser.Common.Localization; -using MediaBrowser.Common.Mef; using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.ScheduledTasks; @@ -11,8 +9,6 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; using System; using System.Collections.Generic; -using System.ComponentModel.Composition; -using System.ComponentModel.Composition.Hosting; using System.Diagnostics; using System.IO; using System.Linq; @@ -183,37 +179,15 @@ namespace MediaBrowser.Common.Kernel /// Gets the list of currently loaded plugins /// </summary> /// <value>The plugins.</value> - [ImportMany(typeof(IPlugin))] public IEnumerable<IPlugin> Plugins { get; protected set; } /// <summary> - /// Gets the list of Scheduled Tasks - /// </summary> - /// <value>The scheduled tasks.</value> - [ImportMany(typeof(IScheduledTask))] - public IEnumerable<IScheduledTask> ScheduledTasks { get; private set; } - - /// <summary> /// Gets the web socket listeners. /// </summary> /// <value>The web socket listeners.</value> - [ImportMany(typeof(IWebSocketListener))] public IEnumerable<IWebSocketListener> WebSocketListeners { get; private set; } /// <summary> - /// Gets the list of Localized string files - /// </summary> - /// <value>The string files.</value> - [ImportMany(typeof(LocalizedStringData))] - public IEnumerable<LocalizedStringData> StringFiles { get; private set; } - - /// <summary> - /// Gets the MEF CompositionContainer - /// </summary> - /// <value>The composition container.</value> - private CompositionContainer CompositionContainer { get; set; } - - /// <summary> /// The _HTTP manager /// </summary> /// <value>The HTTP manager.</value> @@ -226,25 +200,17 @@ namespace MediaBrowser.Common.Kernel public TcpManager TcpManager { get; private set; } /// <summary> - /// Gets the task manager. - /// </summary> - /// <value>The task manager.</value> - public TaskManager TaskManager { get; private set; } - - /// <summary> - /// Gets the iso manager. - /// </summary> - /// <value>The iso manager.</value> - public IIsoManager IsoManager { get; private set; } - - /// <summary> /// Gets the rest services. /// </summary> /// <value>The rest services.</value> - [ImportMany(typeof(IRestfulService))] public IEnumerable<IRestfulService> RestServices { get; private set; } /// <summary> + /// The disposable parts + /// </summary> + private readonly List<IDisposable> _disposableParts = new List<IDisposable>(); + + /// <summary> /// The _protobuf serializer initialized /// </summary> private bool _protobufSerializerInitialized; @@ -265,7 +231,7 @@ namespace MediaBrowser.Common.Kernel get { // Lazy load - LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => DynamicProtobufSerializer.Create(Assemblies)); + LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => DynamicProtobufSerializer.Create(AllTypes)); return _protobufSerializer; } private set @@ -336,29 +302,35 @@ namespace MediaBrowser.Common.Kernel protected IApplicationHost ApplicationHost { get; private set; } /// <summary> + /// Gets or sets the task manager. + /// </summary> + /// <value>The task manager.</value> + protected ITaskManager TaskManager { get; set; } + + /// <summary> /// Gets the assemblies. /// </summary> /// <value>The assemblies.</value> - public Assembly[] Assemblies { get; private set; } + protected Assembly[] Assemblies { get; private set; } + + /// <summary> + /// Gets all types. + /// </summary> + /// <value>All types.</value> + public Type[] AllTypes { get; private set; } /// <summary> /// Initializes a new instance of the <see cref="BaseKernel{TApplicationPathsType}" /> class. /// </summary> /// <param name="appHost">The app host.</param> - /// <param name="isoManager">The iso manager.</param> /// <param name="logger">The logger.</param> /// <exception cref="System.ArgumentNullException">isoManager</exception> - protected BaseKernel(IApplicationHost appHost, IIsoManager isoManager, ILogger logger) + protected BaseKernel(IApplicationHost appHost, ILogger logger) { if (appHost == null) { throw new ArgumentNullException("appHost"); } - - if (isoManager == null) - { - throw new ArgumentNullException("isoManager"); - } if (logger == null) { @@ -366,7 +338,6 @@ namespace MediaBrowser.Common.Kernel } ApplicationHost = appHost; - IsoManager = isoManager; Logger = logger; } @@ -419,7 +390,7 @@ namespace MediaBrowser.Common.Kernel await OnConfigurationLoaded().ConfigureAwait(false); DisposeTaskManager(); - TaskManager = new TaskManager(this, Logger); + TaskManager = new TaskManager(Logger); Logger.Info("Loading Plugins"); await ReloadComposableParts().ConfigureAwait(false); @@ -460,25 +431,82 @@ namespace MediaBrowser.Common.Kernel Assemblies = GetComposablePartAssemblies().ToArray(); - CompositionContainer = MefUtils.GetSafeCompositionContainer(Assemblies.Select(i => new AssemblyCatalog(i))); - - ComposeExportedValues(CompositionContainer); + AllTypes = Assemblies.SelectMany(GetTypes).ToArray(); - CompositionContainer.ComposeParts(this); + ComposeParts(AllTypes); await OnComposablePartsLoaded().ConfigureAwait(false); + } + + /// <summary> + /// Composes the parts. + /// </summary> + /// <param name="allTypes">All types.</param> + private void ComposeParts(IEnumerable<Type> allTypes) + { + var concreteTypes = allTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray(); + + RegisterExportedValues(); + + FindParts(concreteTypes); + } + + /// <summary> + /// Composes the parts with ioc container. + /// </summary> + /// <param name="allTypes">All types.</param> + protected virtual void FindParts(Type[] allTypes) + { + RestServices = GetExports<IRestfulService>(allTypes); + WebSocketListeners = GetExports<IWebSocketListener>(allTypes); + Plugins = GetExports<IPlugin>(allTypes); + + var tasks = GetExports<IScheduledTask>(allTypes, false); + + TaskManager.AddTasks(tasks); + } + + /// <summary> + /// Gets the exports. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="allTypes">All types.</param> + /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param> + /// <returns>IEnumerable{``0}.</returns> + protected IEnumerable<T> GetExports<T>(Type[] allTypes, bool manageLiftime = true) + { + var currentType = typeof(T); + + Logger.Info("Composing instances of " + currentType.Name); - CompositionContainer.Catalog.Dispose(); + var parts = allTypes.Where(currentType.IsAssignableFrom).Select(Instantiate).Cast<T>().ToArray(); + + if (manageLiftime) + { + _disposableParts.AddRange(parts.OfType<IDisposable>()); + } + + return parts; + } + + /// <summary> + /// Instantiates the specified type. + /// </summary> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + private object Instantiate(Type type) + { + return ApplicationHost.CreateInstance(type); } /// <summary> /// Composes the exported values. /// </summary> /// <param name="container">The container.</param> - protected virtual void ComposeExportedValues(CompositionContainer container) + protected virtual void RegisterExportedValues() { - container.ComposeExportedValue("logger", Logger); - container.ComposeExportedValue("appHost", ApplicationHost); + ApplicationHost.Register<IKernel>(this); + ApplicationHost.Register(TaskManager); } /// <summary> @@ -546,6 +574,31 @@ namespace MediaBrowser.Common.Kernel } /// <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> + /// <param name="assembly">The assembly.</param> + /// <returns>IEnumerable{Type}.</returns> + /// <exception cref="System.ArgumentNullException">assembly</exception> + private static IEnumerable<Type> GetTypes(Assembly assembly) + { + if (assembly == null) + { + throw new ArgumentNullException("assembly"); + } + + try + { + return assembly.GetTypes(); + } + catch (ReflectionTypeLoadException ex) + { + // If it fails we can still get a list of the Types it was able to resolve + return ex.Types.Where(t => t != null); + } + } + + /// <summary> /// Fires after MEF finishes finding composable parts within plugin assemblies /// </summary> /// <returns>Task.</returns> @@ -553,11 +606,6 @@ namespace MediaBrowser.Common.Kernel { return Task.Run(() => { - foreach (var task in ScheduledTasks) - { - task.Initialize(this, Logger); - } - // Start-up each plugin Parallel.ForEach(Plugins, plugin => { @@ -608,22 +656,11 @@ namespace MediaBrowser.Common.Kernel { DisposeTcpManager(); DisposeTaskManager(); - DisposeIsoManager(); DisposeHttpManager(); DisposeComposableParts(); - } - } - /// <summary> - /// Disposes the iso manager. - /// </summary> - private void DisposeIsoManager() - { - if (IsoManager != null) - { - IsoManager.Dispose(); - IsoManager = null; + _disposableParts.Clear(); } } @@ -668,9 +705,9 @@ namespace MediaBrowser.Common.Kernel /// </summary> protected virtual void DisposeComposableParts() { - if (CompositionContainer != null) + foreach (var part in _disposableParts) { - CompositionContainer.Dispose(); + part.Dispose(); } } |
