如何从另一个仅在运行时知道的Dart包中加载代码?

时间:2015-02-16 19:58:15

标签: dart

我正在构建一个Dart应用程序。它需要从第三方软件包加载代码,该软件包仅在运行时才知道。我的申请需要:

  1. 自动发现依赖
  2. 从该依赖项加载库
  3. 与依赖项交互
  4. 理想情况下,我不希望要求我的用户指定第三方依赖项。应用程序应该自动发现依赖项。

    例如,工作流程可能是这样的:

    1. 用户安装我的应用(pub global activate my_app
    2. 用户安装"插件" (pub global activate plugin_for_my_app
    3. 用户运行我的应用(my_app
    4. 该应用会自动发现plugin_for_my_app存在。
    5. 该应用加载插件(可能通过spawnUri?)
    6. 应用程序调用插件
    7. 要求:

      1. 必须从命令行运行。
      2. 必须适用于Windows,Mac,Linux。
      3. 编译为JavaScript时应该(但不必)运行。
      4. pub run支持是可选的(pub run使其变得棘手,因为它会重写您的导入URI,因此不是必需的)
      5. 最好的方法是什么?

4 个答案:

答案 0 :(得分:3)

此软件包https://pub.dartlang.org/packages/plugins似乎完全符合您的要求(尽管我自己还没有使用它),只需将插件加载到隔离区中即可。

答案 1 :(得分:3)

在插件包中,目前无法通过pub解析依赖关系。当我最初设计API时,假设已经通过pub get检索了依赖项。话虽如此,文件系统上的插件发现很简单。

正如您在README中的示例中所看到的,加载插件就像new PluginManager().loadAll(String directory)一样简单,它会自动发现目录中的所有插件并加载它们。如果所有插件都在一个文件夹中,这个解决方案是理想的。

如果它遵循插件目录结构,也可以进行单独的插件目录加载。使用PluginLoader,您可以加载一个包含必要文件的目录,以便插件正常运行。没有必要致电load(),因为PluginManager将为您负责调用。

加载插件的简化方法

  1. 实例化PluginManager

    PluginManager pm = new PluginManager();

  2. 确定要加载的插件。插件库将自动进行 确定pub缓存目录。根据pub的文档,还支持PUB_CACHE环境变量。

  3. 加载插件。返回Future,其中包含Plugin对象,该对象提供有关插件的基本信息。该插件需要pubspec.yaml,其中包含名称,包目录和bin/main.dart源文件。但是我们从pub缓存加载,所以我们不需要担心插件的设置,唯一的要求是pub缓存中的包支持插件包。

  4. pm.loadFromCache("test-1.0.0").then((Plugin plugin) {
        print("Plugin loaded!");
        handle();
    });
    
    1. 在您想要加载的所有插件都已初始化之后,管理员现在可以正确地侦听请求。只需使用听众即可查看'传入的数据。
    2. 插件端

      该插件只使用plugins API提供的接收器。

      void main(List<String> args, SendPort port) {
          Receiver rec = new Receiver(port);
          rec.listen((Map<dynamic, dynamic> data) {
              print("Received data: $data");
          });
      }
      

答案 2 :(得分:2)

我用一点糖包装plugins包来提供一些额外的东西,比如声明性的RPC。它非常灵活,而且samrg472(plugins.dart的作者)是一位好朋友,所以我也请他发表评论。

https://github.com/PolymorphicBot/PolymorphicBot/blob/master/lib/src/core/plugins/handler.dart

答案 3 :(得分:2)

这不是直接回答问题(按要求提供CL工具),但我在浏览器中使用plugins并希望分享我的“模式”。

我的Web应用程序导入includes.dart,这是一个动态生成的文件,用于导入在指定目录中找到的所有.dart个文件。文件在应用程序启动后由后端生成(重新)生成,就在将文件提供给浏览器之前。找到的.dart文件实现了公共API(例如init()run()),以便主应用程序可以调用它们的代码。 plugin代码不会加载到单独的隔离区中,而是在与主应用程序相同的隔离区中执行,这样可以使plugins共享相同的堆,并且您可以访问{{1}直接代码。此解决方案还假设plugin解决了自己的依赖关系。

此设置适用于我的用例。但是,由于在Dart中没有真正的动态代码重新加载(但是,我希望看到https://code.google.com/p/dart/issues/detail?id=10530),加载新代码总是需要刷新步骤。