115 lines
7.3 KiB
C#
115 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Prise.Activation;
|
|
using Prise.AssemblyLoading;
|
|
using Prise.AssemblyScanning;
|
|
using Prise.Proxy;
|
|
|
|
namespace Prise.DependencyInjection
|
|
{
|
|
public static class ServiceCollectionExtensions
|
|
{
|
|
/// <summary>
|
|
/// This bootstrapper adds the basic Prise services as well as the IPluginLoader
|
|
/// </summary>
|
|
/// <param name="serviceLifetime">The path to the directory to scan for plugins</param>
|
|
/// <returns>A ServiceCollection that has the following types registered and ready for injection:
|
|
/// <see cref="IAssemblyScanner"/>, <see cref="IPluginTypeSelector"/>, <see cref="IParameterConverter"/> ,<see cref="IResultConverter"/>, <see cref="IPluginActivator"/>, <see cref="IAssemblyLoader"/> and <see cref="IPluginLoader"/>
|
|
/// </returns>
|
|
public static IServiceCollection AddPrise(this IServiceCollection services,
|
|
ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
|
|
{
|
|
return services
|
|
// Add all the factories
|
|
.AddFactory<IAssemblyScanner>(DefaultFactories.DefaultAssemblyScanner, serviceLifetime)
|
|
.AddFactory<IPluginTypeSelector>(DefaultFactories.DefaultPluginTypeSelector, serviceLifetime)
|
|
.AddFactory<IParameterConverter>(DefaultFactories.DefaultParameterConverter, serviceLifetime)
|
|
.AddFactory<IResultConverter>(DefaultFactories.DefaultResultConverter, serviceLifetime)
|
|
.AddFactory<IPluginActivator>(DefaultFactories.DefaultPluginActivator, serviceLifetime)
|
|
.AddFactory<IAssemblyLoader>(DefaultFactories.DefaultAssemblyLoader, serviceLifetime)
|
|
// Add the loader
|
|
.AddService(new ServiceDescriptor(typeof(IPluginLoader), typeof(DefaultPluginLoader), serviceLifetime))
|
|
;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This bootstrapper adds the basic Prise services, the IPluginLoader and support to load Prise NuGet Packages
|
|
/// </summary>
|
|
/// <param name="serviceLifetime">The path to the directory to scan for plugins</param>
|
|
/// <returns>A ServiceCollection that has the following types registered and ready for injection:
|
|
/// <see cref="IAssemblyScanner"/>, <see cref="IPluginTypeSelector"/>, <see cref="IParameterConverter"/> ,<see cref="IResultConverter"/>, <see cref="IPluginActivator"/>, <see cref="IAssemblyLoader"/> and <see cref="IPluginLoader"/>
|
|
/// </returns>
|
|
public static IServiceCollection AddPriseNugetPackages(this IServiceCollection services,
|
|
ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
|
|
{
|
|
return services
|
|
// Add all the factories
|
|
.AddFactory<IAssemblyScanner>(DefaultFactories.DefaultNuGetAssemblyScanner, serviceLifetime)
|
|
.AddFactory<IPluginTypeSelector>(DefaultFactories.DefaultPluginTypeSelector, serviceLifetime)
|
|
.AddFactory<IParameterConverter>(DefaultFactories.DefaultParameterConverter, serviceLifetime)
|
|
.AddFactory<IResultConverter>(DefaultFactories.DefaultResultConverter, serviceLifetime)
|
|
.AddFactory<IPluginActivator>(DefaultFactories.DefaultPluginActivator, serviceLifetime)
|
|
.AddFactory<IAssemblyLoader>(DefaultFactories.DefaultAssemblyLoader, serviceLifetime)
|
|
// Add the loader
|
|
.AddService(new ServiceDescriptor(typeof(IPluginLoader), typeof(DefaultPluginLoader), serviceLifetime))
|
|
;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is the bootstrapper method to register a Plugin of <see cref="{T}"> using Prise
|
|
/// </summary>
|
|
/// <param name="pathToPlugin">The path to start scanning for plugins</param>
|
|
/// <param name="hostFramework">The framework of the host, optional</param>
|
|
/// <param name="allowMultiple">If <true>, an <see cref="IEnumerable<{T}>"/> is registered, all plugins of this type will have the same configuration. If <false> only the first found Plugin is registered</param>
|
|
/// <param name="configureContext">A builder function that you can use configure the load context</param>
|
|
/// <typeparam name="T">The Plugin type</typeparam>
|
|
/// <returns>A full configured ServiceCollection that will resolve <see cref="{T}"/> or an <see cref="IEnumerable<{T}>"/> based on <allowMultiple></returns>
|
|
public static IServiceCollection AddPrise<T>(this IServiceCollection services,
|
|
Func<IServiceProvider, string> pathToPlugin,
|
|
Func<IServiceProvider, string> hostFramework = null,
|
|
bool allowMultiple = false,
|
|
ServiceLifetime serviceLifetime = ServiceLifetime.Scoped,
|
|
Action<PluginLoadContext> configureContext = null)
|
|
where T : class
|
|
{
|
|
return services
|
|
.AddPrise(serviceLifetime) // Adds the default Prise Services
|
|
.AddService(new ServiceDescriptor(allowMultiple ? typeof(IEnumerable<T>) : typeof(T), (sp) =>
|
|
{
|
|
var loader = sp.GetRequiredService<IPluginLoader>();
|
|
var scanResults = loader.FindPlugins<T>(pathToPlugin.Invoke(sp)).Result;
|
|
if (!scanResults.Any())
|
|
throw new PriseDependencyInjectionException($"No plugin assembly was found for plugin type {typeof(T).Name}");
|
|
|
|
if (!allowMultiple) // Only 1 plugin is requested
|
|
return loader.LoadPlugin<T>(scanResults.First(), hostFramework?.Invoke(sp), configureContext).Result;
|
|
|
|
var plugins = new List<T>();
|
|
foreach (var scanResult in scanResults)
|
|
plugins.AddRange(loader.LoadPlugins<T>(scanResult, hostFramework?.Invoke(sp), configureContext).Result);
|
|
|
|
return plugins;
|
|
}, serviceLifetime))
|
|
;
|
|
}
|
|
|
|
public static IServiceCollection AddFactory<T>(this IServiceCollection services, Func<T> func, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
|
|
where T : class
|
|
{
|
|
Func<IServiceProvider, Func<T>> factoryOfFuncT = (sp) => func;
|
|
Func<IServiceProvider, T> factoryOfT = (sp) => sp.GetRequiredService<Func<T>>()() as T;
|
|
return services
|
|
.AddService(new ServiceDescriptor(typeof(Func<T>), factoryOfFuncT, serviceLifetime))
|
|
.AddService(new ServiceDescriptor(typeof(T), factoryOfT, serviceLifetime));
|
|
}
|
|
|
|
private static IServiceCollection AddService(this IServiceCollection services, ServiceDescriptor serviceDescriptor)
|
|
{
|
|
services
|
|
.Add(serviceDescriptor);
|
|
return services;
|
|
}
|
|
}
|
|
} |