Skip to content

Commit f8dce34

Browse files
committed
Add ability to explicitly inject RedisSentinelManager by contract
Signed-off-by: Cy Rossignol <[email protected]>
1 parent 4a0e2b2 commit f8dce34

8 files changed

+121
-12
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Contents
3939
- [Hybrid Configuration][s-hybrid-config]
4040
- [Override the Standard Redis API][s-override-redis-api]
4141
- [Executing Redis Commands (RedisSentinel Facade)][s-facade]
42+
- [Dependency Injection][s-dependency-injection]
4243
- [Testing](#testing)
4344
- [License](#license)
4445
- [Appendix: Environment Variables][s-appx-env-vars]
@@ -625,6 +626,37 @@ In Lumen, add the alias to *bootstrap/app.php*:
625626
class_alias('Monospice\LaravelRedisSentinel\RedisSentinel', 'RedisSentinel');
626627
```
627628

629+
### Dependency Injection
630+
631+
For those that prefer to declare the Redis Sentinel manager as a dependency of
632+
a class rather than using the facade, we can type-hint the interface that the
633+
container will resolve when building an object from the container:
634+
635+
```php
636+
use Monospice\LaravelRedisSentinel\Contracts\Factory as RedisSentinel;
637+
...
638+
public function __construct(RedisSentinel $sentinel)
639+
{
640+
$sentinel->get('some-key');
641+
}
642+
```
643+
644+
The above explicitly requests an instance of the package's Sentinel service. If
645+
we [override the Redis API][s-override-redis-api], we can use the standard
646+
Redis contract instead, and the application will inject the appropriate service
647+
based on the configuration:
648+
649+
```php
650+
use Illuminate\Contracts\Redis\Factory as Redis;
651+
...
652+
public function __construct(Redis $redis)
653+
{
654+
// Either a Sentinel connection or a standard Redis connection depending on
655+
// the value of REDIS_DRIVER or config('database.redis.driver'):
656+
$redis->get('some-key');
657+
}
658+
```
659+
628660
Testing
629661
-------
630662

@@ -948,6 +980,7 @@ Sentinel Documentation][sentinel].
948980

949981
[s-appx-env-vars]: #appendix-environment-variables
950982
[s-appx-examples]: #appendix-configuration-examples
983+
[s-dependency-injection]: #dependency-injection
951984
[s-dev-vs-prod-example]: #development-vs-production
952985
[s-env-config]: #environment-based-configuration
953986
[s-env-config-examples]: #environment-based-configuration-examples

src/Contracts/Factory.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Monospice\LaravelRedisSentinel\Contracts;
4+
5+
use Illuminate\Contracts\Redis\Factory as RedisFactoryContract;
6+
7+
interface Factory extends RedisFactoryContract
8+
{
9+
}

src/Manager/VersionedRedisSentinelManager.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Support\Arr;
77
use InvalidArgumentException;
88
use Monospice\LaravelRedisSentinel\Connectors;
9+
use Monospice\LaravelRedisSentinel\Contracts\Factory;
910

1011
/**
1112
* Contains common functionality for the RedisSentinelManager implementations
@@ -17,7 +18,9 @@
1718
* @license See LICENSE file
1819
* @link http://github.com/monospice/laravel-redis-sentinel-drivers
1920
*/
20-
abstract class VersionedRedisSentinelManager extends RedisManager
21+
abstract class VersionedRedisSentinelManager
22+
extends RedisManager
23+
implements Factory
2124
{
2225
/**
2326
* Get the Redis Connection instance represented by the specified name

src/RedisSentinelManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Monospice\LaravelRedisSentinel;
44

5-
use Illuminate\Contracts\Redis\Factory;
5+
use Monospice\LaravelRedisSentinel\Contracts\Factory;
66
use Monospice\LaravelRedisSentinel\Manager\VersionedRedisSentinelManager;
77
use Monospice\SpicyIdentifiers\DynamicMethod;
88

src/RedisSentinelServiceProvider.php

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Support\Arr;
1111
use Illuminate\Support\ServiceProvider;
1212
use Monospice\LaravelRedisSentinel\Configuration\Loader as ConfigurationLoader;
13+
use Monospice\LaravelRedisSentinel\Contracts\Factory;
1314
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
1415

1516
/**
@@ -58,6 +59,23 @@ public function register()
5859
{
5960
$this->config = ConfigurationLoader::load($this->app);
6061

62+
$this->registerServices();
63+
64+
// If we want Laravel's Redis API to use Sentinel, we'll return an
65+
// instance of the RedisSentinelManager when requesting the "redis"
66+
// service:
67+
if ($this->config->shouldOverrideLaravelRedisApi) {
68+
$this->registerOverrides();
69+
}
70+
}
71+
72+
/**
73+
* Register the core Redis Sentinel connection manager.
74+
*
75+
* @return void
76+
*/
77+
protected function registerServices()
78+
{
6179
$this->app->singleton('redis-sentinel', function ($app) {
6280
$class = $this->config->getVersionedRedisSentinelManagerClass();
6381
$config = $this->config->get('database.redis-sentinel', [ ]);
@@ -66,12 +84,11 @@ public function register()
6684
return new RedisSentinelManager(new $class($driver, $config));
6785
});
6886

69-
// If we want Laravel's Redis API to use Sentinel, we'll return an
70-
// instance of the RedisSentinelManager when requesting the "redis"
71-
// service:
72-
if ($this->config->shouldOverrideLaravelRedisApi) {
73-
$this->registerOverrides();
74-
}
87+
$this->app->singleton('redis-sentinel.manager', function ($app) {
88+
return $app->make('redis-sentinel')->getVersionedManager();
89+
});
90+
91+
$this->app->alias('redis-sentinel', Factory::class);
7592
}
7693

7794
/**
@@ -87,7 +104,7 @@ protected function registerOverrides()
87104
});
88105

89106
$this->app->bind('redis.connection', function ($app) {
90-
return $app->make('redis-sentinel')->connection();
107+
return $app->make('redis-sentinel.manager')->connection();
91108
});
92109
}
93110

@@ -140,7 +157,7 @@ protected function addRedisSentinelBroadcaster()
140157
{
141158
$this->app->make(BroadcastFactory::class)
142159
->extend('redis-sentinel', function ($app, $conf) {
143-
$redis = $app->make('redis-sentinel')->getVersionedManager();
160+
$redis = $app->make('redis-sentinel.manager');
144161
$connection = Arr::get($conf, 'connection', 'default');
145162

146163
return new RedisBroadcaster($redis, $connection);
@@ -158,7 +175,7 @@ protected function addRedisSentinelCacheStore()
158175
$cache = $this->app->make('cache');
159176

160177
$cache->extend('redis-sentinel', function ($app, $conf) use ($cache) {
161-
$redis = $app->make('redis-sentinel')->getVersionedManager();
178+
$redis = $app->make('redis-sentinel.manager');
162179
$prefix = $app->make('config')->get('cache.prefix');
163180
$connection = Arr::get($conf, 'connection', 'default');
164181
$store = new RedisStore($redis, $prefix, $connection);
@@ -195,7 +212,7 @@ protected function addRedisSentinelSessionHandler()
195212
protected function addRedisSentinelQueueConnector()
196213
{
197214
$this->app->make('queue')->extend('redis-sentinel', function () {
198-
$redis = $this->app->make('redis-sentinel')->getVersionedManager();
215+
$redis = $this->app->make('redis-sentinel.manager');
199216

200217
return new RedisConnector($redis);
201218
});

tests/RedisSentinelManagerTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Contracts\Redis\Factory as RedisFactory;
66
use Illuminate\Redis\Connections\Connection;
7+
use Monospice\LaravelRedisSentinel\Contracts\Factory as RedisSentinelFactory;
78
use Monospice\LaravelRedisSentinel\Manager\VersionedRedisSentinelManager;
89
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
910
use Mockery;
@@ -58,6 +59,11 @@ public function testImplementsRedisFactoryForSwapability()
5859
$this->assertInstanceOf(RedisFactory::class, $this->manager);
5960
}
6061

62+
public function testIsRedisSentinelFactory()
63+
{
64+
$this->assertInstanceOf(RedisSentinelFactory::class, $this->manager);
65+
}
66+
6167
public function testGetsVersionedRedisSentinelManagerInstance()
6268
{
6369
$this->assertInstanceOf(

tests/RedisSentinelServiceProviderTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
77
use Illuminate\Contracts\Redis\Factory as RedisFactory;
88
use Illuminate\Redis\RedisManager;
9+
use Monospice\LaravelRedisSentinel\Contracts\Factory as RedisSentinelFactory;
10+
use Monospice\LaravelRedisSentinel\Manager\VersionedRedisSentinelManager;
911
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
1012
use Monospice\LaravelRedisSentinel\RedisSentinelServiceProvider;
1113
use Monospice\LaravelRedisSentinel\Tests\Support\ApplicationFactory;
@@ -84,6 +86,31 @@ public function testRegistersWithApplication()
8486

8587
$service = $this->app->make('redis-sentinel');
8688

89+
$this->assertInstanceOf(RedisSentinelManager::class, $service);
90+
$this->assertInstanceOf(RedisFactory::class, $service);
91+
$this->assertInstanceOf(RedisSentinelFactory::class, $service);
92+
}
93+
94+
public function testRegistersVersionedManagerWithApplication()
95+
{
96+
$this->provider->register();
97+
98+
$this->assertArrayHasKey('redis-sentinel.manager', $this->app);
99+
100+
$service = $this->app->make('redis-sentinel.manager');
101+
102+
$this->assertInstanceOf(RedisFactory::class, $service);
103+
$this->assertInstanceOf(RedisSentinelFactory::class, $service);
104+
}
105+
106+
public function testAliasesContractForInjection()
107+
{
108+
$this->provider->register();
109+
110+
$this->assertArrayHasKey(RedisSentinelFactory::class, $this->app);
111+
112+
$service = $this->app->make(RedisSentinelFactory::class);
113+
87114
$this->assertInstanceOf(RedisSentinelManager::class, $service);
88115
$this->assertInstanceOf(RedisFactory::class, $service);
89116
}
@@ -96,6 +123,7 @@ public function testRegisterPreservesStandardRedisApi()
96123
$redisService = $this->app->make('redis');
97124

98125
$this->assertInstanceOf(RedisManager::class, $redisService);
126+
$this->assertNotInstanceOf(RedisSentinelManager::class, $redisService);
99127
}
100128

101129
public function testRegisterOverridesStandardRedisApi()
@@ -107,6 +135,7 @@ public function testRegisterOverridesStandardRedisApi()
107135
$redisService = $this->app->make('redis');
108136

109137
$this->assertInstanceOf(RedisSentinelManager::class, $redisService);
138+
$this->assertInstanceOf(RedisSentinelFactory::class, $redisService);
110139
}
111140

112141
public function testBootExtendsBroadcastConnections()

tests/VersionedRedisSentinelManagerTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
namespace Monospice\LaravelRedisSentinel\Tests;
44

55
use Closure;
6+
use Illuminate\Contracts\Redis\Factory as RedisFactory;
67
use Illuminate\Redis\RedisManager;
78
use InvalidArgumentException;
9+
use Monospice\LaravelRedisSentinel\Contracts\Factory as RedisSentinelFactory;
810
use Monospice\LaravelRedisSentinel\Manager;
911
use Monospice\LaravelRedisSentinel\Tests\Support\ApplicationFactory;
1012
use PHPUnit_Framework_TestCase as TestCase;
@@ -55,6 +57,16 @@ public function testExtendsRedisManagerForSwapability()
5557
$this->assertInstanceOf(RedisManager::class, $this->manager);
5658
}
5759

60+
public function testIsRedisFactory()
61+
{
62+
$this->assertInstanceOf(RedisFactory::class, $this->manager);
63+
}
64+
65+
public function testIsRedisSentinelFactory()
66+
{
67+
$this->assertInstanceOf(RedisSentinelFactory::class, $this->manager);
68+
}
69+
5870
public function testCreatesSentinelPredisClientsForEachConnection()
5971
{
6072
$client1 = $this->manager->connection('connection1');

0 commit comments

Comments
 (0)