在前面的文章中,我们介绍了如何在.NET Interactive notebook绘制图表和执行SQL。
那么,能不能为.NET Interactive开发交互功能呢?
今天,我们就来演示如何实现。
创建项目
新建类库项目Demo1Extension,需要引用Nuget包Microsoft.DotNet.Interactive
和Microsoft.DotNet.Interactive.CSharp
。注意:需要选择“包含预发新版”
修改项目文件,增加项目配置:
<ItemGroup>
<None Include="$(OutputPath)/Demo1Extension.dll" Pack="true" PackagePath="interactive-extensions/dotnet" />
</ItemGroup>
指定PackagePath
不能改,否则无法加载扩展
新增自定义扩展类
创建Demo1KernelExtension
类,实现IKernelExtension
。
这里有个坑: 类名必须以KernelExtension
结尾,否则无法加载扩展。这个默认规则太隐晦了,害我试了半天。
自定义格式化
可以为指定Type实现自定义格式化输出。
这里我们以string
为例:
public class Demo1KernelExtension : IKernelExtension
{
public Task OnLoadAsync(Microsoft.DotNet.Interactive.Kernel kernel)
{
//指定输出格式
Formatter.SetPreferredMimeTypeFor(typeof(string), HtmlFormatter.MimeType);
Formatter.Register<string>((str, writer) =>
{
writer.Write(DrawHtml(str));
}, HtmlFormatter.MimeType);
return Task.CompletedTask;
}
public static IHtmlContent DrawHtml(string str)
{
var id = "div" + Guid.NewGuid().ToString("N");
var div = PocketViewTags.div[id: id](
PocketViewTags.h1[style: "color:#F00"](str.ToString()));
return div;
}
}
我们将输入的字符串格式化成了Html输出,格式为“<div id='xxx'><h1 style='color:#F00'>输入字符串</h1></div>”。
测试
首先,执行下面命令,生成Nuget包:
dotnet build
dotnet pack /p:PackageVersion=1.0.0
然后,在VS Code中创建.NET Interactive notebook,并引用上面生成的Nuget包:
#i D:\codes\Demo1Extension\Demo1Extension\bin\Debug
#r "nuget:Demo1Extension,1.0.0"
由于我们刚才生成的Nuget包还在本地,所以需要用#i
命令设置加载位置。
出现下面提示,就表明扩展加载成功,否则请检查上面说过的注意事项:
输入一个字符串,执行,返回正常:
自定义命令
还可以实现自定义命令。
这里,我们增加了一个#!demo1
命令,它接受一个字符串参数,并输出Html:
public Task OnLoadAsync(Microsoft.DotNet.Interactive.Kernel kernel)
{
var command = new Command("#!demo1", "it's a demo extension");
command.AddArgument(new Argument());
command.Handler = CommandHandler.Create(
(string str, KernelInvocationContext invocationContext) =>
{
invocationContext.Display(DrawHtml("demo1: "+str));
});
kernel.AddDirective(command);
return Task.CompletedTask;
}
再次生成Nuget包并引用,记得修改一下版本号。
执行命令,返回正常:
结论
在本文中,我们演示了如何创建.NET Interactive notebook自定义扩展。
关于自定义扩展的详细API,可以参看官方文档:https://github.com/dotnet/interactive/blob/main/docs/extending-dotnet-interactive.md。
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!