Files
SQLLint/SQLLinter/Infrastructure/Plugins/PluginHandler.cs

131 lines
4.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using SQLLinter.Common;
using SQLLinter.Common.Helpers;
using SQLLinter.Core.Interfaces;
using SQLLinter.Infrastructure.Parser;
namespace SQLLinter.Infrastructure.Plugins
{
public class PluginHandler : IPluginHandler
{
private readonly IConfig _config;
private readonly IAssemblyWrapper _assemblyWrapper;
private readonly IReporter _reporter;
private readonly IFileversionWrapper _versionWrapper;
private List<Type> _ruleTypes = new();
private Dictionary<string, IRule> _rules = new();
public IList<IRule> Rules => _rules.Values.ToList();
public IDictionary<string, IRule> RuleWithNames => _rules;
public PluginHandler(IReporter reporter, IConfig config)
: this(reporter, new AssemblyWrapper(), new VersionInfoWrapper(), config) { }
public PluginHandler(
IReporter reporter,
IAssemblyWrapper assemblyWrapper,
IFileversionWrapper versionWrapper,
IConfig config
)
{
this._reporter = reporter;
this._assemblyWrapper = assemblyWrapper;
this._versionWrapper = versionWrapper;
this._config = config;
LoadDefaultRules();
LoadPlugins();
}
private void ActivatePlugin(Type type)
{
var instance = (IRule?)Activator.CreateInstance(type);
if (instance == null)
{
_reporter.Report($"Ошибка создания экземпляра правила '{type.FullName}'");
return;
}
var ruleName = instance.Name;
if (_config.Rules.TryGetValue(ruleName, out var severity))
{
instance.Severity = severity;
}
if (instance.Severity == RuleViolationSeverity.Off)
{
_reporter.Report($"Правило '{ruleName}' выключено");
return;
}
if (_rules.ContainsKey(ruleName))
{
_reporter.Report($"Ошибка добавления правила '{type.FullName}': правило '{ruleName}' уже создано");
return;
}
_rules.Add(ruleName, instance);
_reporter.Report($"Правило '{ruleName}' ({instance.Severity}) добавлено с типом '{type.FullName}'");
}
private void LoadDefaultRules()
{
//Загрузка дефолтных правил
var defaultRuleTypes = RuleVisitorFriendlyNameTypeMap.DefaultRuleTypes;
defaultRuleTypes.ForEach(AddRuleType);
}
private void AddRuleType(Type ruleType)
{
if (_ruleTypes.Contains(ruleType))
{
_reporter.Report($"Уже загружено правило '{ruleType.FullName}'");
return;
}
_ruleTypes.Add(ruleType);
_reporter.Report($"Добавлено правило '{ruleType.FullName}'");
ActivatePlugin(ruleType);
}
private void LoadPlugins()
{
var paths = FileHelpers.FindFilesWithMask(_config.Plugins);
//Загрузка плагинов
foreach (var path in paths)
{
if (!File.Exists(path))
{
_reporter.Report($"Ошибка загрузки плагина '{path}': Файл не найден.");
}
else if (Path.GetExtension(path)?.ToLower() != "dll")
{
_reporter.Report($"Ошибка загрузки плагина '{path}': Неподдерживаемый формат файла. Ожидается файл с расширением .dll.");
}
else
{
LoadPlugin(path);
}
}
}
private void LoadPlugin(string path)
{
var dll = _assemblyWrapper.LoadFrom(path);
var version = _versionWrapper.GetVersion(dll);
foreach (var type in _assemblyWrapper.GetExportedTypes(dll))
{
var rules = RuleVisitorFriendlyNameTypeMap.GetRuleTypes(dll);
rules.ForEach(AddRuleType);
}
}
}
}