Представьте себе что-то вроде:
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 немного сложно инициализировать, я бы не хотел обновлять его при каждом запросе. Я также не хочу, чтобы он сохранял его в переменной пакета. Есть ли что-то в Dancer2 или какой-то другой трюк, который позволит мне внедрять такие сервисы?
Мне нравится инициализировать классы стиля обслуживания с помощью Bread::Board, а затем предоставлять их глобально через пространство имен, например MyApp::Service
, что-то вроде:
package MyApp::Service;
use Bread::Board;
# Generate service depdencencies with Bread::Board
my $c = container 'MyApp' => as {
container 'Service' => as {
service 'hello_service' => (
lifecycle => 'Singleton',
block => sub {
require MyApp::Service::HelloService;
my $s = shift; # Use $s to resolve dependencies
return MyApp::Service::HelloService->new; # Do args and stuff here
}
);
};
};
no Bread::Board;
# Retrieve via MyApp::Service::hello_service
sub hello_service { return $c->resolve('Service/hello_service') }
Может быть другой способ сделать это, но я всегда делал это для Mojolicious
, Dancer
и т. д. Я знаю, что вы упомянули, что не хотите делать это в переменной пакета (извините).
@Jan Да, MyApp::Service->hello_service->greet('world');
должен подойти, есть несколько действительно крутых вещей, которые вы можете делать с DI, так что обязательно прочитайте об этом.
Итак, в моем коде 'get' я бы назвал MyApp::Service::hello_service()->greet('world'), верно?