Merge pull request #4253 from BaronGreenback/fordiscussion

DI in plugins
This commit is contained in:
Bond-009 2020-11-15 13:29:04 +01:00 committed by GitHub
commit 331c7f8481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 54 deletions

View File

@ -133,6 +133,33 @@ namespace Emby.Server.Implementations.AppBase
}
}
/// <summary>
/// Manually pre-loads a factory so that it is available pre system initialisation.
/// </summary>
/// <typeparam name="T">Class to register.</typeparam>
public virtual void RegisterConfiguration<T>()
where T : IConfigurationFactory
{
IConfigurationFactory factory = Activator.CreateInstance<T>();
if (_configurationFactories == null)
{
_configurationFactories = new[] { factory };
}
else
{
var oldLen = _configurationFactories.Length;
var arr = new IConfigurationFactory[oldLen + 1];
_configurationFactories.CopyTo(arr, 0);
arr[oldLen] = factory;
_configurationFactories = arr;
}
_configurationStores = _configurationFactories
.SelectMany(i => i.GetConfigurations())
.ToArray();
}
/// <summary>
/// Adds parts.
/// </summary>

View File

@ -126,7 +126,6 @@ namespace Emby.Server.Implementations
private IMediaEncoder _mediaEncoder;
private ISessionManager _sessionManager;
private IHttpClientFactory _httpClientFactory;
private string[] _urlPrefixes;
/// <summary>
@ -497,24 +496,11 @@ namespace Emby.Server.Implementations
HttpsPort = ServerConfiguration.DefaultHttpsPort;
}
if (Plugins != null)
{
var pluginBuilder = new StringBuilder();
foreach (var plugin in Plugins)
{
pluginBuilder.Append(plugin.Name)
.Append(' ')
.Append(plugin.Version)
.AppendLine();
}
Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString());
}
DiscoverTypes();
RegisterServices();
RegisterPluginServices();
}
/// <summary>
@ -779,10 +765,24 @@ namespace Emby.Server.Implementations
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
_plugins = GetExports<IPlugin>()
.Select(LoadPlugin)
.Where(i => i != null)
.ToArray();
if (Plugins != null)
{
var pluginBuilder = new StringBuilder();
foreach (var plugin in Plugins)
{
pluginBuilder.Append(plugin.Name)
.Append(' ')
.Append(plugin.Version)
.AppendLine();
}
Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString());
}
_urlPrefixes = GetUrlPrefixes().ToArray();
Resolve<ILibraryManager>().AddParts(
@ -812,21 +812,6 @@ namespace Emby.Server.Implementations
Resolve<IIsoManager>().AddParts(GetExports<IIsoMounter>());
}
private IPlugin LoadPlugin(IPlugin plugin)
{
try
{
plugin.RegisterServices(ServiceCollection);
}
catch (Exception ex)
{
Logger.LogError(ex, "Error loading plugin {PluginName}", plugin.GetType().FullName);
return null;
}
return plugin;
}
/// <summary>
/// Discovers the types.
/// </summary>
@ -837,6 +822,22 @@ namespace Emby.Server.Implementations
_allConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray();
}
private void RegisterPluginServices()
{
foreach (var pluginServiceRegistrator in GetExportTypes<IPluginServiceRegistrator>())
{
try
{
var instance = (IPluginServiceRegistrator)Activator.CreateInstance(pluginServiceRegistrator);
instance.RegisterServices(ServiceCollection);
}
catch (Exception ex)
{
Logger.LogError(ex, "Error registering plugin services from {Assembly}.", pluginServiceRegistrator.Assembly);
}
}
}
private IEnumerable<Type> GetTypes(IEnumerable<Assembly> assemblies)
{
foreach (var ass in assemblies)

View File

@ -46,6 +46,13 @@ namespace MediaBrowser.Common.Configuration
/// <param name="newConfiguration">The new configuration.</param>
void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration);
/// <summary>
/// Manually pre-loads a factory so that it is available pre system initialisation.
/// </summary>
/// <typeparam name="T">Class to register.</typeparam>
void RegisterConfiguration<T>()
where T : IConfigurationFactory;
/// <summary>
/// Gets the configuration.
/// </summary>

View File

@ -83,16 +83,6 @@ namespace MediaBrowser.Common.Plugins
{
}
/// <inheritdoc />
public virtual void RegisterServices(IServiceCollection serviceCollection)
{
}
/// <inheritdoc />
public virtual void UnregisterServices(IServiceCollection serviceCollection)
{
}
/// <inheritdoc />
public void SetAttributes(string assemblyFilePath, string dataFolderPath, Version assemblyVersion)
{
@ -185,6 +175,11 @@ namespace MediaBrowser.Common.Plugins
/// <value>The type of the configuration.</value>
public Type ConfigurationType => typeof(TConfigurationType);
/// <summary>
/// Gets or sets the event handler that is triggered when this configuration changes.
/// </summary>
public EventHandler<BasePluginConfiguration> ConfigurationChanged { get; set; }
/// <summary>
/// Gets the name the assembly file.
/// </summary>
@ -280,6 +275,8 @@ namespace MediaBrowser.Common.Plugins
Configuration = (TConfigurationType)configuration;
SaveConfiguration();
ConfigurationChanged.Invoke(this, configuration);
}
/// <inheritdoc />

View File

@ -62,18 +62,6 @@ namespace MediaBrowser.Common.Plugins
/// Called when just before the plugin is uninstalled from the server.
/// </summary>
void OnUninstalling();
/// <summary>
/// Registers the plugin's services to the service collection.
/// </summary>
/// <param name="serviceCollection">The service collection.</param>
void RegisterServices(IServiceCollection serviceCollection);
/// <summary>
/// Unregisters the plugin's services from the service collection.
/// </summary>
/// <param name="serviceCollection">The service collection.</param>
void UnregisterServices(IServiceCollection serviceCollection);
}
public interface IHasPluginConfiguration

View File

@ -0,0 +1,19 @@
namespace MediaBrowser.Common.Plugins
{
using Microsoft.Extensions.DependencyInjection;
/// <summary>
/// Defines the <see cref="IPluginServiceRegistrator" />.
/// </summary>
public interface IPluginServiceRegistrator
{
/// <summary>
/// Registers the plugin's services with the service collection.
/// </summary>
/// <remarks>
/// This interface is only used for service registration and requires a parameterless constructor.
/// </remarks>
/// <param name="serviceCollection">The service collection.</param>
void RegisterServices(IServiceCollection serviceCollection);
}
}