dbMango/Rms.Risk.Mango/PluginSupport.cs
Alexander Shabarshov 2a7a24c9e7 Initial contribution
2025-11-03 14:43:26 +00:00

123 lines
3.7 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* dbMango
*
* Copyright 2025 Deutsche Bank AG
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Rms.Risk.Mango.Interfaces;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Rms.Risk.Mango;
public static partial class PluginSupport
{
[GeneratedRegex(@"^.*Mango.*Plugin\.dll$")]
private static partial Regex PluginNameMask();
private static readonly List<Assembly> _loaded = [];
private static IDbMangoPlugin? _plugin;
public static List<Assembly> GetPluginAssemblies(ILogger? logger)
{
if ( _loaded.Count > 0 )
return _loaded;
var basePath = AppContext.BaseDirectory;
if (!Directory.Exists(basePath))
return _loaded;
var pluginFiles = Directory.GetFiles(basePath, "*.dll", SearchOption.TopDirectoryOnly)
.Where(file => PluginNameMask().IsMatch(file));
_loaded.AddRange(pluginFiles.Select(LoadPlugin).OfType<Assembly>());
if ( _loaded.Count > 0 )
logger?.LogInformation("Plugin assemblies loaded:\n{Join}", string.Join("\n\t", _loaded.Select(x => x.FullName)));
else
logger?.LogInformation("No plugin assemblies loaded");
return _loaded;
}
public static IDbMangoPlugin? GetPlugin(ILogger? logger = null)
{
if ( _plugin != null )
return _plugin;
string? pluginClassName = GetPluginClassName();
var assemblies = GetPluginAssemblies(logger);
var type = assemblies
.SelectMany(x => x.GetTypes().Where(t => ( string.IsNullOrWhiteSpace(pluginClassName) || t.Name == pluginClassName) && t.GetInterface(nameof(IDbMangoPlugin)) != null ))
.FirstOrDefault()
;
if ( type == null )
return null;
_plugin = (IDbMangoPlugin?)Activator.CreateInstance(type);
if ( _loaded.Count > 0 )
logger?.LogInformation("Plugin selected:\n{type}", type);
else
logger?.LogInformation("No plugin selected");
return _plugin;
}
private static string? GetPluginClassName()
{
var args = Environment.GetCommandLineArgs();
// Check for "--plugin" argument and extract the plugin class name
string? pluginClassName = null;
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "--plugin-class-name" && i + 1 < args.Length)
{
pluginClassName = args[i + 1];
break;
}
}
if (!string.IsNullOrWhiteSpace(pluginClassName))
{
return pluginClassName.Trim();
}
pluginClassName = Environment.GetEnvironmentVariable("DBMANGO_PLUGIN_CLASS_NAME");
if (!string.IsNullOrWhiteSpace(pluginClassName))
{
return pluginClassName.Trim();
}
return null;
}
private static Assembly? LoadPlugin(string pluginPath)
{
if (!File.Exists(pluginPath))
return null;
try
{
var assembly = Assembly.LoadFrom(pluginPath);
return assembly;
}
catch (Exception)
{
return null;
}
}
}