如果您不想分离您的 UserRepository 和 CachedUserRepository 实现,您可以简单地将缓存添加到您的 UserRepository:
use Psr\SimpleCache\CacheInterface;
class UserRepository implements UserRepositoryInterface
{
protected $client;
protected $cache;
private static $dependencies = [
'Cache' => '%$' . CacheInterface::class . '.userrepository',
];
public function __construct(Client $client)
{
$this->client = $client;
}
public function getAll()
{
if (!$this->cache->get('fetchUsers')) {
$users = $this->client->fetchUsers();
$this->cache->set('fetchUsers', $users);
}
return $this->cache->get('fetchUsers');
}
public function setCache(CacheInterface $cache)
{
$this->cache = $cache;
return $this;
}
}
还有一些用于注册缓存的 YAML 配置:
SilverStripe\Core\Injector\Injector:
Psr\SimpleCache\CacheInterface.userrepository:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: userrepository
如果您想以与您链接的文章中类似的方式分离实现,您可以执行与文章中类似的操作,但您需要定义自己的与 UserRepository 交互的方法,因为SilverStripe 没有这种开箱即用的 API。
例如,像这样的:
class CachedUserRepository implements UserRepositoryInterface
{
protected $repository;
protected $cache;
private static $dependencies = [
'Cache' => '%$' . CacheInterface::class . '.userrepository',
];
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
public function getAll()
{
if (!$this->cache->get('fetchUsers')) {
$users = $this->repository->getAll();
$this->cache->set('fetchUsers', $users);
}
return $this->cache->get('fetchUsers');
}
public function setCache(CacheInterface $cache)
{
$this->cache = $cache;
return $this;
}
}
我猜你会这样实例化它:
$repository = Injector::inst()->create(CachedUserRepository::class, [
Injector::inst()->get(UserRepository::class),
]);
请注意,使用 Injector 实例化您的类非常重要,以便在构造后注册通过 $dependencies 进行的依赖注入。
为了与 SilverStripe 中的依赖注入模式保持一致,您可能还希望以相同的方式将 Client 注入到 UserRepository 中,并以相同的方式将 UserRepository 注入到 CachedUserRepository 中(构造函数已删除,但未在这些示例中显示。
用户存储库:
private static $dependencies = [
'Client' => '%$' . Client::class,
];
public function setClient(Client $client)
{
$this->client = $client;
return $this;
}
CachedUserRepository:
private static $dependencies = [
'Cache' => '%$' . CacheInterface::class . '.userrepository',
'Repository' => '%$' . UserRepository::class,
];
public function setRepository(UserRepository $repository)
{
$this->repository = $repository;
return $this;
}
现在 Injector 将为您处理所有依赖注入,因此您的实现将如下所示:
$repository = Injector::inst()->get(CachedUserRepository::class);
您可以更进一步(这是 SilverStripe 4 中的一种常见模式)并为您的接口定义一个具体的实现,因此该实现不需要知道要使用哪个类:
# File: app/_config/repositories.yml
SilverStripe\Core\Injector\Injector:
UserRepositoryInterface:
# Define the repository you want by default
class: CachedUserRepository
现在您可以像这样获取您的存储库(默认缓存):
$repository = Injector::inst()->get(UserRepositoryInterface::class);