Во-первых, вы смотрите на это с ног на голову и назад. Наличие некоторого сервиса, добавляющего вещи в кеш, а затем имеющего другой код просто , предполагает , что вещи в кеше готовы к работе, - это путь к катастрофе. Вместо этого пусть ваш зависимый код буквально запрашивает необходимые данные, а затем, если вы хотите его кэшировать, сделайте это методом, который извлекает данные. Таким образом, код вашего приложения не зависит от того, откуда поступают данные; он просто вызывает метод и получает нужные данные. Под капотом он либо извлекается из базы данных, либо из кэша, в зависимости от того, какой из них доступен / предпочтителен.
В любом случае, ваша служба кэширования имеет серьезные проблемы. Во-первых, это не должен быть синглтон, во-первых. Нет причин для этого, и, поскольку вы имеете дело с внутренними службами, вы только усложняете вещи, которые им необходимы. Во-вторых, вы никогда не должны использовать ввод / вывод в конструкторе. Там должна быть сделана только простая инициализация переменной / проп. Все, что требует реальной работы, должно входить в метод. Если вы действительно хотите что-то сделать при инициализации, вам следует реализовать фабричный шаблон. Например, у вас может быть что-то вроде CacheServiceFactory
с методом Create
, который возвращает полностью экземплярный CacheService
, включая вызов любых методов, выполняющих реальную работу.
Как правило, если не принимать во внимание заявления об отказе от ответственности, чтобы использовать сервис с областью действия в одиночном коде, вы должны создать область действия. Это должно быть сделано каждый раз, когда вы хотите использовать сервис; вы не можете сохранить службу ивару в своем синглтон-классе. Просто вы вводите IServiceProvider
в свой класс, который сам по себе имеет одинарную область видимости, поэтому у вас не возникнет проблем с этим. Затем, когда вам нужно использовать сервис с определенной областью:
using (var scope = provider.CreateScope())
{
var repo = scope.ServiceProvider.GetRequiredService<IUserRepository>();
// do something with repo
}
Это называется анти-паттерном поиска сервисов. Это называется так, потому что это то, что вы действительно должны избегать. Иногда это не всегда возможно. Однако чаще всего вы можете просто разрабатывать вещи по-другому: например, чтобы сама служба работала с областью действия.