高级依赖配置
本文档详细介绍如何在插件中实现复杂的依赖验证逻辑。如果您想了解主程序是如何解析这些依赖的,请参阅架构文档中的 依赖解析机制。
依赖声明 (基础回顾)
我们在 插件结构 中已经介绍了 Dependencies 属性。它用于声明您的插件必须依赖哪些其他插件才能运行。
csharp
public IReadOnlyDictionary<string, string> Dependencies => new Dictionary<string, string>
{
{ "Sharw.Core", ">=1.0.0" }
};自定义验证逻辑 (ValidateDependency)
当您的依赖需求超出了简单的“名称+版本范围”时(例如可选依赖、互斥检查),您需要重写 ValidateDependency 方法。
场景一:可选依赖 (Optional Dependency)
有些插件可以独立运行,但如果检测到环境中存在另一个插件,它会开启额外功能。此时,您可能需要检查那个“可选伙伴”的版本是否足够新。
csharp
public bool ValidateDependency(IReadOnlyDictionary<string, string> validPlugins)
{
// "OptionalFeaturePlugin" 不是必须的,所以不在 Dependencies 中声明。
// 但如果它存在,我们希望确保它至少是 2.0 版本,否则为了兼容性,我们可以选择不加载自己,或者仅仅是在日志中记录警告(但在本方法中只能决定是否加载自己)。
// 注意:传入的 validPlugins 只包含已通过第一阶段(强依赖检查)的有效插件,不是所有候选插件。
if (validPlugins.TryGetValue("OptionalFeaturePlugin", out var versionStr))
{
var version = Version.Parse(versionStr);
if (version.Major < 2)
{
// 如果可选依赖版本过低,您可以选择拒绝加载,防止运行时向其发送不兼容的调用
Console.WriteLine($"[警告] 检测到 OptionalFeaturePlugin 但版本 {version} 过低,本插件无法兼容,停止加载。");
return false;
}
}
return true; // 验证通过
}场景二:冲突检测 (Conflict Detection)
如果您的插件与另一个插件功能完全冲突,不能同时存在。
csharp
public bool ValidateDependency(IReadOnlyDictionary<string, string> validPlugins)
{
// 注意:validPlugins 只包含已通过第一阶段强依赖检查的插件
if (validPlugins.ContainsKey("My.Rival.Plugin"))
{
// 发现死对头插件,拒绝加载
return false;
}
return true;
}验证流程
- 收集候选插件:主程序扫描并加载所有插件程序集,形成“候选插件列表”。
- 第一阶段(声明式):遍历每个插件的
Dependencies属性,验证强依赖是否满足。 - 第二阶段(自定义):对满足强依赖的插件,调用
ValidateDependency。- 如果返回
true:插件进入“有效插件列表”。 - 如果返回
false:插件被拒绝加载,且不会影响其他插件(除非其他插件依赖于它)。
- 如果返回
注意事项
保持轻量
ValidateDependency 在插件生命周期的早期执行,此时依赖注入容器尚未构建。请不要尝试在此处访问数据库或配置文件,仅进行基于插件元数据的逻辑判断。
日志记录
此方法目前没有直接传入 ILogger(因为容器还没准备好)。如果验证失败,建议通过 Console 或抛出带有详细信息的异常来告知用户原因,主程序捕获异常时会记录它。