pschelpdesk/Vendor/Prise/Activation/DefaultPluginServiceProvider.cs
2024-11-04 20:45:34 +01:00

116 lines
4.7 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Prise.Utils;
namespace Prise.Activation
{
public class DefaultBootstrapperServiceProvider : IBootstrapperServiceProvider
{
protected IServiceProvider localProvider;
protected IEnumerable<Type> hostTypes;
protected ConcurrentBag<object> instances;
public DefaultBootstrapperServiceProvider(IServiceProvider localProvider, IEnumerable<Type> hostTypes)
{
this.localProvider = localProvider.ThrowIfNull(nameof(localProvider));
this.hostTypes = hostTypes.ThrowIfNull(nameof(hostTypes));
this.instances = new ConcurrentBag<object>();
}
public virtual object GetHostService(Type type)
{
var hostType = this.hostTypes.FirstOrDefault(t => t.Name == type.Name);
if (hostType == null)
throw new PluginActivationException($"An instance of type {type.Name} is required to activate this plugin, but it was not registered as a Host Type, please configure this type via the UseHostServices, ConfigureHostServices or ConfigureSharedServices builder method.");
var instance = this.localProvider.GetService(hostType);
if (instance == null)
throw new PluginActivationException($"An instance of Host Service type {type.Name} could not be properly constructed (null).");
this.instances.Add(instance);
return instance;
}
protected bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed && disposing)
{
foreach (var instance in this.instances)
(instance as IDisposable)?.Dispose();
this.instances.Clear();
this.instances = null;
this.localProvider = null;
this.hostTypes = null;
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public class DefaultPluginServiceProvider : DefaultBootstrapperServiceProvider, IPluginServiceProvider
{
private IEnumerable<Type> pluginTypes;
public DefaultPluginServiceProvider(IServiceProvider localProvider, IEnumerable<Type> hostTypes, IEnumerable<Type> pluginTypes)
: base(localProvider, hostTypes)
{
this.pluginTypes = pluginTypes;
}
public object GetPluginService(Type type)
{
// Plugin services are registered via a PluginBootstrapper, eventually they'll land inside the localProvider.
var pluginType = this.pluginTypes.FirstOrDefault(t => t.Name == type.Name);
if (pluginType == null)
throw new PluginActivationException($"An instance of type {type.Name} is required to activate this plugin, but it was not registered as a Plugin Type, please provide this service via a PluginBootstrapper builder.");
var instance = this.localProvider.GetService(type);
if (instance == null)
throw new PluginActivationException($"An instance of Plugin Service type {type.Name} could not be properly constructed (null).");
this.instances.Add(instance);
return instance;
}
public override object GetHostService(Type type)
{
// Host services are provided by the Host.
var hostType = this.hostTypes.FirstOrDefault(t => t.Name == type.Name);
if (hostType == null)
throw new PluginActivationException($"An instance of type {type.Name} is required to activate this plugin, but it was not registered as a Host Type, please configure this type via the UseHostServices, ConfigureHostServices or ConfigureSharedServices builder method.");
var instance = this.localProvider.GetService(hostType);
if (instance == null)
throw new PluginActivationException($"An instance of Host Service type {type.Name} could not be properly constructed (null).");
this.instances.Add(instance);
return instance;
}
protected override void Dispose(bool disposing)
{
if (!this.disposed && disposing)
{
foreach (var instance in this.instances)
(instance as IDisposable)?.Dispose();
this.instances.Clear();
this.instances = null;
this.localProvider = null;
this.hostTypes = null;
this.pluginTypes = null;
}
this.disposed = true;
}
}
}