数据源插件
一、接口定义
ISourceProvider
定义了用于获取数据源的方法,如果你要开发新的数据源插件,可以引用 CodeBuilder.Core.dll
,并实现 ISourceProvider
接口。
namespace CodeBuilder.Core
{
/// <summary>
/// 数据源提供者插件。
/// </summary>
public interface ISourceProvider : IPlugin
{
/// <summary>
/// 连接数据源,获取预览表。
/// </summary>
/// <param name="option">选项。</param>
/// <returns></returns>
Task<List<Table>> PreviewAsync(SourceOption option, CancellationToken cancellationToken = default);
/// <summary>
/// 从历史中加载数据源
/// </summary>
/// <param name="history"></param>
/// <param name="option"></param>
/// <returns></returns>
Task<List<Table>> FromHistoryAsync(object history, SourceOption option, CancellationToken cancellationToken = default);
/// <summary>
/// 获取指定表的架构。
/// </summary>
/// <param name="tables">选定的数据表。</param>
/// <param name="processHandler">数据表的读取进度通知。</param>
/// <returns></returns>
Task<List<Table>> GetSchemaAsync(List<Table> tables, TableSchemaProcessHandler processHandler, CancellationToken cancellationToken = default);
/// <summary>
/// 获取历史记录。
/// </summary>
/// <returns></returns>
IEnumerable<object> GetHistory();
/// <summary>
/// 清空历史记录
/// </summary>
void ClearHistory();
}
}
以 Database
为例,下面的流程图诠释了该接口的调用步骤:
💡 多说一句
PreviewAsync
方法只需要读入表的信息,勾选完表后,再使用 GetSchemaAsync
方法读入字段、主键、外键等信息。
二、插件导入
编写好插件后,需要使用 MEF
进行入导入。如下所示,使用 ExportAttribute
特性即可:
namespace CodeBuilder.Database
{
[Export(typeof(ISourceProvider))]
public class SourceProvider : ISourceProvider
{
//略去
}
}
将编写的项目编译成 *.dll
后拷贝到 CodeBuilder 运行目录即可自动安装。
三、关于历史记录
从以上流程图中可看出,使用数据源后,会将连接或文件等信息写入到历史文件中,通过【资源窗口】加载出来,方便以后快速打开。
GetHistory
和 FromHistoryAsync
方法都是操作 object
类型的对象,你可以定义任何结构,但是必须重写 ToString
方法,因为【资源窗口】是使用该方法输出的文本来显示到表格里的。
四、提供配置支持
可向【选项】对话框中提供一个配置面板,以增强插件的功能。实现 IConfigureSupported
接口,并提供一个用户控件即可。用户控件实现 IConfigurableControl
接口后,可感知变更触发【选项】对话框关闭前的检查。如下所示:
[Export(typeof(ISourceProvider))]
public class SourceProvider : ISourceProvider, IConfigureSupported
{
UserControl IConfigureSupported.GetOptionPanel()
{
return new OptionPanel();
}
}
public partial class OptionPanel : UserControl, IConfigurableControl
{
private bool _isChanged;
bool IConfigurableControl.IsChanged => _isChanged;
void IConfigurableControl.Close()
{
base.DestroyHandle();
}
}