Я бы вообще не использовал static
ness и проверку на нуль из вашего кода - создавайте нормальные классы без одноэлементной разводки по умолчанию и размещайте этот аспект поверх контейнера. То же самое, снимите зависимость от инъекции свойства - инъекция ctor всегда лучше, если у вас нет выбора
т.е:.
class TemplateManager
{
readonly IRepository<Template> _templateRepository;
public TemplateManager(IRepository<Template> templateRepository)
{
_templateRepository = templateRepository;
}
public ITemplate LoadRoot()
{
return _templateRepository.Retrieve(1); // obviously better logic here.
}
}
class TemplateModule : Module
{
public void Load()
{
Bind<ITemplate>().ToMethod(() => kernel.Get<TemplateManager>().LoadRoot()).InSingletonScope();
}
}
И тогда я бы задал вопрос, должен ли TemplateManager стать провайдером или стать участником.
Что касается самого вопроса ... Большой вопрос в том, как и когда вы хотите контролировать очистку кэша для принудительной перезагрузки, если вы решили, что кэширование должно быть на уровне сеанса, а не на уровне приложения из-за влияния авторизации на шаблон дерева? В общем, я бы сказал, что это должно быть заботой о реальном классе, а не быть привязанным к проводке вашего DI или жестко привязанным к тому, является ли класс статическим или одноэлементным (как в шаблоне проектирования, а не в целевой области).
Я бы хотел иметь класс TemplateManager без статических методов и сделать его одноэлементным классом в контейнере. Однако, чтобы получить корневой шаблон, потребители должны вставить TemplateManager (через ctor), а затем сказать _templateManager.GetRootTemplate (), чтобы получить шаблон.
Таким образом, вы можете:
- не полагайтесь на провайдеров фантазии и / или привязывайте себя к своему контейнеру
- не имеет синглтон-флюта или статических методов
- имеет простую логику кэширования в
TemplateManager
- изменить область видимости менеджера без изменения всего клиентского кода
- ясно, что получение шаблона может быть, а может и не быть простой операцией get
То есть я бы справился так:
class TemplateManager
{
readonly IRepository<Template> _templateRepository;
public TemplateManager(IRepository<Template> templateRepository)
{
_templateRepository = templateRepository;
}
ITemplate _cachedRootTemplate;
ITemplate FetchRootTemplate()
{
if(_cachedRootTemplate==null)
_cachedRootTemplate = LoadRootTemplate();
return _cachedRootTemplate;
}
ITemplate LoadRoot()
{
return _templateRepository.Retrieve(1); // obviously better logic here.
}
}
зарегистрируйте это так:
class TemplateModule : Module
{
public void Load()
{
Bind<TemplateManager>().ToSelf().InSingletonScope();
}
}
и затем потребляйте его так:
class TemplateConsumer
{
readonly TemplateManager _templateManager;
public TemplateConsumer(TemplateManager templateManager)
{
_templateManager = templateManager;
}
void DoStuff()
{
var rootTempalte = _templateManager.FetchRootTemplate();
Дикие предположения: я бы также подумал о том, чтобы не иметь отдельного IRepository, разрешимого в контейнере (и
предположительно имея все виды связей в единицах работы). Вместо этого я бы хотел, чтобы TemplateRepository был более долгоживущим, не связанным со слоем ORM и единицей работы. То есть наличие репозитория и менеджера, ни один из которых не выполняет ничего четко определенного самостоятельно, не является хорошим знаком - репозиторий должен быть не просто шлюзом табличных данных - он должен быть тем местом, где кэшируется агрегированный корень, такой как шаблоны и сопоставлены вместе. Но я должен был бы узнать намного больше о вашей кодовой базе, прежде чем выделять подобные вещи без контекста!