5

鉴于使用大量中间件组件的示例 plack 应用程序和在构建器中启用的 mojolicious 应用程序(见下文),我如何在不使用显示的丑陋 %ENV hack 的情况下将参数从 app.psgi 传递给 Mojolicious?当然,传递配置只是一个示例,它可以是任何标量/对象。

应用程序.psgi

use Plack::Builder;

$ENV{CONFIG} = {...};

builder {
    ...
    Mojolicious::Commands->start_app('MyApp');
};

我的应用程序.pm

package MyApp;

use Mojo::Base 'Mojolicious';

sub startup {

    my $self = shift;
    my $r = $self->routes;

    $self->config( $ENV{CONFIG} );

    $r->route('/')->to('home#');        
}
4

1 回答 1

2

这是一个有趣的问题,通过查看源代码很容易解决。在您的示例中,您正确使用

Mojolicious::Commands->start_app('MyApp');

查看源代码表明这start_app是一个相当简单的包装器:

sub start_app {
  my $self = shift;
  return Mojo::Server->new->build_app(shift)->start(@_);
}

事实证明build_app也是如此

sub build_app {
  my ($self, $app) = @_;
  local $ENV{MOJO_EXE};
  return $app->new unless my $e = Mojo::Loader->new->load($app);
  die ref $e ? $e : qq{Couldn't find application class "$app".\n};
}

返回应用程序类的新实例。Mojolicious 类的new功能比较复杂,但最后只是调用熟悉的startup方法并返回实例

这意味着您不能轻松地将参数startup从您的中间件包装器中传递给以标准方式使用的方法。我可以想到两种机制来完成您想要做的事情:1)编写自己的build_app函数来替换服务器的方法,但将参数$app->new传递给(依次传递给)或 2)编写可以调用另一个startup的自己的函数类功能。start_appstartup

# in MyApp.pm

sub startup {
  ... # as before
}

sub after_startup {
  ... # your new code here,
      # or even most of what was in `startup` before
}

# app.psgi

builder {
  ...
  my $app = Mojo::Server->new->build_app(shift);
  $app->after_startup(@your_args_here);
  $app->start(@_);
}
于 2013-07-14T18:52:05.053 回答