当我的代码被拆分成多个文件时,如何使用 Dancer2::Plugin::Database?

How can I use Dancer2::Plugin::Database when my code is split into multiple files?

我看到的所有与 Dancer2 和数据库连接相关的代码示例都将所有 Dancer2 代码直接放在附加到各种 'get' 和 'put' 请求的匿名子例程中。

我想以 myServices.pm 文件本质上只是包含正在执行的内容的其他代码文件的路由器的方式组织我的代码。我可以在 MyServices::Submission 模块中成功使用 params 关键字。但是,在这种情况下,我似乎无法使用 Dancer2::Plugin::Database 中的数据库关键字。

myServices.pm:

package myServices;

use Dancer2;
use Dancer2::Plugin::REST;
use Dancer2::Plugin::Database;
use Data::Dumper;
use MyServices::Submission;

get '/direct' => sub {
    my $dbh = database;
    return 'success';
};

get '/indirect' => sub {
   MyServices::Submission::databaseTest();
};

true;

MyServices/Submission.pm:

package MyServices::Submission;

use Dancer2;
use Dancer2::Plugin::REST;
use Dancer2::Plugin::Database;
use Data::Dumper;


sub databaseTest{
    my $dbh = database;
    return 'success';
}

true;

调用/direct returns 'success'.
调用 /indirect returns 错误 500 - 消息为 "Can't get a database connection without settings supplied!" 的内部服务器错误。然后它会打印出我的设置,包括正确的数据库配置。

我的配置文件肯定没问题,因为调用/direct 成功了。

问题:

  1. 其他人能复制这种行为吗? (确保我没有失踪 很明显。)
  2. 有没有办法在MyServices::Submission模块中成功使用Dancer2::Plugin::Database,或者 我是否需要搜索另一个数据库连接解决方​​案才能 满足我的代码组织需求?

当您在 MyServices::Submission 中调用 use Dancer2; 时,you're actually creating a separate Dancer2 app:

As soon as you import Dancer2 (by calling use Dancer2), you create a Dancer2 App. It will use your class name (defined by either the package function in Perl or the default in Perl: main) to define the Dancer2 App name. This is how Dancer2 will recognize your application.

This introduces an interesting situation. If you wish to separate your App to multiple files, you're actually creating multiple applications.

So what?

This means that any engine defined in an application, because the application is a complete separate scope, will not be available to a different application:

package MyApp::User {
      use Dancer2;
      set serializer => 'JSON';
      get '/view' => sub {...};
 }

package MyApp::User::Edit {
     use Dancer2;
     get '/edit' => sub {...};
 }

These are two different Dancer2 Apps. They have different scopes, contexts, and thus different engines. While MyApp::User has a serializer (the JSON one) defined, MyApp::User::Edit will not have that configuration.


您可以在导入 Dancer2 时使用 appname 选项来表示您的模块应该扩展应用程序而不是创建新应用程序:

package MyServices::Submission;

use Dancer2 appname => 'MyApp';
use Dancer2::Plugin::Database;

sub databaseTest {
    my $dbh = database;                                 
    return 'success';
}

1;

现在主应用程序的配置和引擎将在 MyServices::Submission 中可用。您甚至可以在此处添加其他路线。


顺便说一句,像这样拆分您的应用程序是个好主意;如果您对其他技术感兴趣,Dancer 用户邮件列表中的某个人在 how to organize medium- to large-scale Dancer applications. The recommendations are split into six parts; see here 上写了一些非常详尽的建议以获取完整列表。