In Dancer2, what is the preferred way to keep an instance of a service-like object, that a module's routes methods can access?

huangapple go评论55阅读模式
英文:

In Dancer2, what is the preferred way to keep an instance of a service-like object, that a module's routes methods can access?

问题

get( => 'hello' => sub ($app) {
my $hello_service = $app->get_instance_of('hello_service');
my $message = $hello_service->greet('world');
template 'hello', {message => $message};
});

hello_service it a bit complex to initialize, I would not want to have to new it up on every request. I also don't want it to store it in package variable. Is there something in Dancer2 or some other trick that could allow me injecting services like that?

英文:

Imagine something along the lines of:

get( => 'hello' => sub ($app) {
    my $hello_service = $app->get_instance_of('hello_service');
    my $message = $hello_service->greet('world');
    template 'hello', {message => $message};
});

hello_service it a bit complex to initialize, I would not want to have to new it up on every request. I also don't want it to store it in package variable. Is there something in Dancer2 or some other trick that could allow me injecting services like that?

答案1

得分: 2

我喜欢使用[Bread::Board](https://metacpan.org/pod/Bread::Board)来初始化我的服务样式类然后通过一个类似`MyApp::Service`的命名空间将它们全局暴露代码示例如下

```perl
package MyApp::Service;

use Bread::Board;

# 使用Bread::Board生成服务依赖
my $c = container 'MyApp' => as {
    container 'Service' => as {
        service 'hello_service' => (
            lifecycle => 'Singleton',
            block     => sub {
                require MyApp::Service::HelloService;
                my $s = shift; # 使用 $s 来解析依赖
                return MyApp::Service::HelloService->new; # 在这里执行参数等操作
            }
        );
    };
};

no Bread::Board;

# 通过MyApp::Service::hello_service获取
sub hello_service { return $c->resolve('Service/hello_service') }

可能还有其他方法来实现这一点,但这是我一直在为MojoliciousDancer等框架中采用的方式。我知道你提到不想在包变量中实现(抱歉)。


<details>
<summary>英文:</summary>

I like to initialize my service style classes with [Bread::Board](https://metacpan.org/pod/Bread::Board) then expose them globally through a namespace like `MyApp::Service`, something like:

```perl
package MyApp::Service;

use Bread::Board;

# Generate service depdencencies with Bread::Board
my $c = container &#39;MyApp&#39; =&gt; as {
    container &#39;Service&#39; =&gt; as {
        service &#39;hello_service&#39; =&gt; (
            lifecycle =&gt; &#39;Singleton&#39;,
            block     =&gt; sub {
                require MyApp::Service::HelloService;
                my $s = shift; # Use $s to resolve dependencies
                return MyApp::Service::HelloService-&gt;new; # Do args and stuff here
            }
        );
    };
};

no Bread::Board;

# Retrieve via MyApp::Service::hello_service
sub hello_service { return $c-&gt;resolve(&#39;Service/hello_service&#39;) }

There may be another way to do this, but this is the way I've always done it for Mojolicious, Dancer, etc. I know you mentioned not wanting to do it in a package variable (sorry).

huangapple
  • 本文由 发表于 2023年3月31日 22:09:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899500.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定