# NAME

Catalyst::Plugin::InjectionHelpers - Enhance Catalyst Component Injection

# SYNOPSIS

Use the plugin in your application class:

    package MyApp;
    use Catalyst 'InjectionHelpers';

    MyApp->inject_components(
      'Model::SingletonA' => {
        from_class=>'MyApp::Singleton', 
        adaptor=>'Application', 
        roles=>['MyApp::Role::Foo'],
        method=>'new',
      },
      'Model::SingletonB' => {
        from_class=>'MyApp::Singleton', 
        adaptor=>'Application', 
        method=>sub {
          my ($adaptor_instance, $from_class, $app, %args) = @_;
          return $class->new(aaa=>$args{arg});
        },
      },
    );

    MyApp->config(
      'Model::SingletonA' => { aaa=>100 },
      'Model::SingletonB' => { arg=>300 },
    );

    MyApp->setup;

# DESCRIPTION

This plugin enhances the build in component injection features of [Catalyst](https://metacpan.org/pod/Catalyst)
(since v5.90090) to make it easy to bring non [Catalyst::Component](https://metacpan.org/pod/Catalyst::Component) classes
into your application.  You may consider using this for what you often used
[Catalyst::Model::Adaptor](https://metacpan.org/pod/Catalyst::Model::Adaptor) in the past for (although there is no reason to
stop using that if you are doing so, its not a 'broken' approach, but for the
very simple cases this might suffice and allow you to reduce the number of nearly
empty 'boilerplate' classes in your application.

You should be familiar with how component injection works in newer versions of
[Catalyst](https://metacpan.org/pod/Catalyst) (v5.90090+).

# USAGE

    MyApp->inject_components($model_name => \%args);

Where `$model_name` is the name of the component as it is in your [Catalyst](https://metacpan.org/pod/Catalyst)
application (ie 'Model::User', 'View::HTML', 'Controller::Static') and `%args`
are key /values as described below:

## from\_class

This is the full namespace of the class you are adapting to use as a [Catalyst](https://metacpan.org/pod/Catalyst)
component.

## roles

A list of [Moose::Roles](https://metacpan.org/pod/Moose::Roles)s that will be composed into the 'from\_class' prior
to creating an instance of that class.

## method

Either a string or a coderef. If left empty this defaults to 'new'.

The name of the method used to create the adapted class instance.  Generally this
is 'new'.  If you have complex instantiation requirements you may instead use
a coderef. If so, your coderef will receive four arguments.   The first is the
adaptor instance.  The second is the name of the from\_class.  The third is either
the application or context, depending on the type adaptor.  The forth is a hash
of arguments which merges the global configuration for the named component along
with any arguments passed in the request for the component (this only makes
sense for non application scoped models, btw).

## adaptor

The adaptor used to bring your 'from\_class' into [Catalyst](https://metacpan.org/pod/Catalyst).  Out of the box
there are three adaptors (described in detail below): Application, Factory and
PerRequest.  The default is Application.  You may create your own adaptors; if
you do so you should use the full namespace as the value (MyApp::Adaptors::MySpecialAdaptor).

# ADAPTORS

Out of the box this plugin comes with the following three adaptors. All canonical
adaptors are under the namespace 'Catalyst::Model::InjectionHelpers'.

## Application

Model is application scoped.  This means you get one instance shared for the entire
lifecycle of the application.

## Factory

Model is scoped to the request. Each call to $c->model($model\_name) returns a new
instance of the model.  You may pass additional parameters in the model call,
which are merged to the global parameters defined in configuration and used as
part of the object initialization.

## PerRequest

Model is scoped to the request. The first time in a request that you call for the
model, a new model is created.  After that, all calls to the model return the original
instance, until the request is completed, after which the instance is destroyed when
the request goes out of scope.

The first time you call this model you may pass additional parameters, which get
merged with the global configuration and used to initialize the model.

# Creating your own adaptor

Your new adaptor should consume the role [Catalyst::ModelRole::InjectionHelpers](https://metacpan.org/pod/Catalyst::ModelRole::InjectionHelpers)
and provide a method ACCEPT\_CONTEXT which must return the component you wish to
inject.  Please review the existing adaptors and that role for insights.

# CONFIGURATION

This plugin defines the following possible configuration.  As per [Catalyst](https://metacpan.org/pod/Catalyst)
standards, these configuration keys fall under the 'Plugin::InjectionHelpers'
namespace in the configuration hash.

## adaptor\_namespace

Default namespace to look for adaptors.  Defaults to [Catalyst::Model::InjectionHelpers](https://metacpan.org/pod/Catalyst::Model::InjectionHelpers)

## default\_adaptor

The default adaptor to use, should you not set one.  Defaults to 'Application'.

# PRIOR ART

You may wish to review other similar approach on CPAN:

[Catalyst::Model::Adaptor](https://metacpan.org/pod/Catalyst::Model::Adaptor).

# AUTHOR

John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

# SEE ALSO

[Catalyst](https://metacpan.org/pod/Catalyst), [Catalyst::Model::InjectionHelpers::Application](https://metacpan.org/pod/Catalyst::Model::InjectionHelpers::Application),
[Catalyst::Model::InjectionHelpers::Factory](https://metacpan.org/pod/Catalyst::Model::InjectionHelpers::Factory), [Catalyst::Model::InjectionHelpers::PerRequest](https://metacpan.org/pod/Catalyst::Model::InjectionHelpers::PerRequest)
[Catalyst::ModelRole::InjectionHelpers](https://metacpan.org/pod/Catalyst::ModelRole::InjectionHelpers)

# COPYRIGHT & LICENSE

Copyright 2015, John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
