<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Resource::Silo

A lazy declarative resource managemement library for Perl.

# DESCRIPTION

Declare resources such as configuration files, database connections,
external service endpoints, and so on, using a simple syntax,
and manage their lifecycle.

## Syntax:

* `resource` - a Moose-like prototyped function to declare resources
inside a sealed container class;
* `silo` - a re-exportable function to access
the one and true container instance;
* no limitations on creating more than one container objects or even classes.

## Inside the application:

* acquiring resources on demand as simple as `silo-&gt;my_foo`;
* caching them;
* releasing them in due order when program ends;
* preloading all resources at startup to fail early;
* detecting forks and reinitializing to avoid clashes.

## In test files:

* overriding actual resources with mocks/fixtures;
* locking the container so that no unmocked resources can be acquired.

## In support scripts and tools:

* loading only the needed resources for fast startup time;
* creating isolated one-off resource instances to perform invasive operations
such as a big DB update within a transaction.

## Overall:

* built with simplicity and performance in mind;
* robust and resilient to misuse;
* terse, concise, and laconic.

# USAGE

Declaring a resource:

```perl
    package My::App;
    use Resource::Silo;
    use YAML::XS qw(LoadFile);

    resource config =&gt; sub { LoadFile( "/etc/myapp.yaml" ) };
    resource dbh    =&gt; sub {
      require DBI;
      my $self = shift;
      my $conf = $self-&gt;config-&gt;{database};
      DBI-&gt;connect(
        $conf-&gt;{dbi}, $conf-&gt;{username}, $conf-&gt;{password}, { RaiseError =&gt; 1 }
      );
    };
    resource user_agent =&gt; sub {
        require LWP::UserAgent;
        LWP::UserAgent-&gt;new();
        # set your custon UserAgent header or SSL certificate(s) here
    };
```

Declaring a parametric resource:

```perl
    package My::App;
    use Resource::Silo;

    use Redis;
    use Redis::Namespace;
    resource redis_conn =&gt; sub {
        my $self = shift;
        Redis-&gt;new( server =&gt; $self-&gt;config-&gt;{redis} );
    };
    resource redis =&gt;
        argument      =&gt; sub { $known_namespaces{ $_ } },
        init          =&gt; sub {
            my ($self, $name, $ns) = @_;
            Redis::Namespace-&gt;new(
                redis     =&gt; $self-&gt;redis,
                namespace =&gt; $ns,
            );
        };
```

Using it elsewhere:

```perl
    use My::App qw(silo);

    sub load_foo {
      my $id = shift;
      my $sql = q{SELECT * FROM foo WHERE foo_id = ?};
      silo-&gt;dbh-&gt;fetchrow_hashred( $sql, $id );
    };
```

```perl
    package My::App::Stuff;
    use Moo;
    use My::App qw(silo);
    has dbh =&gt; is =&gt; 'lazy', builder =&gt; sub { silo-&gt;dbh };
```

Using it in test files:

```perl
    use Test::More;
    use My::App qw(silo);

    silo-&gt;ctl-&gt;override( dbh =&gt; $temp_sqlite_connection );
    silo-&gt;ctl-&gt;lock;

    my $stuff = My::App::Stuff-&gt;new();
    $stuff-&gt;frobnicate( ... );        # will only affect the sqlite instance

    $stuff-&gt;ping_partner_api();       # oops! the user_agent resource wasn't
                                      # overridden, so there'll be an exception
```

Performing a Big Scary Update:

```perl
    use My::App qw(silo);
    my $dbh = silo-&gt;ctl-&gt;fresh('dbh');

    $dbh-&gt;begin_work;
    # any operations on $dbh won't interfere with normal DB usage
    # of silo-&gt;dbh by other application classes.
```

# INSTALLATION

To install this module, run the following commands:

	perl Makefile.PL
	make
	make test
	make install

# ACKNOWLEDGEMENTS

The library was named after a building in the game
*Heroes of Might and Magic III: The Restoration of Erathia*.

# LICENSE AND COPYRIGHT

This software is free software.

Copyright (c) 2023 Konstantin Uvarin (khedin@gmail.com).

</pre></body></html>