如何在 silverstripe 4 中使用缓存实现存储库模式?
How can I achieve repository pattern with caching in silverstripe 4?
我有一个第三方 API,我用它来获取用户及其详细信息。如何在 silverstripe 4 中使用缓存实现存储库模式?
我有一个名为 UserRepositoryInterface 的接口
interface UserRepositoryInterface
{
public function getAll();
}
UserRepository,与 API 交互以获取用户及其详细信息
class UserRepository implements UserRepositoryInterface
{
protected $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function getAll()
{
return $this->client->fetchUsers();
}
}
我知道我们需要一个 CachedUserRepository,如果存在则从缓存中获取用户,否则从 API 目录中获取。我将如何继续实施它?
试图在 silverstripe 4
中实现类似的东西 https://laracasts.com/discuss/channels/laravel/repository-pattern-with-caching-laravel?#reply=398497
如果您不想将 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 实例化您的 classes 非常重要,以便在构建后通过 $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 中的一种常见模式)并为您的接口定义一个具体的实现,因此该实现不需要知道将使用哪个 class :
# 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);
我有一个第三方 API,我用它来获取用户及其详细信息。如何在 silverstripe 4 中使用缓存实现存储库模式?
我有一个名为 UserRepositoryInterface 的接口
interface UserRepositoryInterface
{
public function getAll();
}
UserRepository,与 API 交互以获取用户及其详细信息
class UserRepository implements UserRepositoryInterface
{
protected $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function getAll()
{
return $this->client->fetchUsers();
}
}
我知道我们需要一个 CachedUserRepository,如果存在则从缓存中获取用户,否则从 API 目录中获取。我将如何继续实施它?
试图在 silverstripe 4
中实现类似的东西 https://laracasts.com/discuss/channels/laravel/repository-pattern-with-caching-laravel?#reply=398497如果您不想将 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 实例化您的 classes 非常重要,以便在构建后通过 $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 中的一种常见模式)并为您的接口定义一个具体的实现,因此该实现不需要知道将使用哪个 class :
# 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);