В контексте контейнера IoC немного двусмысленно сказать «преобразовать его в одноэлементный».Если вы имеете в виду шаблон проектирования синглтона , вам, вероятно, не следует делать это таким образом, поскольку в мире IoC есть лучшие альтернативы.
Контейнеры IoC выполняют две основные функции: разрешают зависимости между компонентами и управляют временем жизни компонентов.Контейнер управляет временем жизни своих компонентов, решая, когда создавать и уничтожать экземпляры компонентов.
Например, когда вы вызываете container.Resolve<SiteInfo>()
, контейнер должен решить, следует ли повторно использовать существующий экземпляр SiteInfo или создать новый.Как решает контейнер?Что ж, когда вы регистрируете SiteInfo в контейнере, вы можете указать контейнеру, как бы вы хотели, чтобы он вел себя.Если вы зарегистрируете его как Singleton, контейнер создаст экземпляр SiteInfo только при первом вызове container.Resolve<SiteInfo>()
;при последующих вызовах он повторно использует существующий экземпляр SiteInfo.
Преимущество этого метода перед одноэлементным паттерном заключается в гибкости.Если вы используете шаблон проектирования, ваш класс SiteInfo всегда будет одноэлементным (если вы не рефакторинг).Используя контейнер для управления временем жизни, вы можете позже передумать и просто изменить регистрационный код контейнера.Потребители компонента не должны (и не должны) заботиться о том, предоставляет ли контейнер им новый экземпляр или повторно использует существующий - они просто вызывают container.Resolve()
.
Я незнаком с Windsor (я использую Autofac ), но похоже, что у вас есть два способа регистрации компонента как одиночного (я уверен, что кто-то исправит меня, если это не так):
container.AddComponentLifeStyle<SiteInfo>(LifestyleType.Singleton)
или,
container.Register( Component.For<SiteInfo>()
.LifeStyle.Singleton );
Впрочем, слово предостережение.В вашем примере ваш класс SiteInfo зависит от класса _SiteRepository.Поэтому вам также необходимо зарегистрировать экземпляр _SiteRepository в качестве одиночного в контейнере, чтобы он был доступен, когда контейнер разрешает SiteInfo.Этот экземпляр _SiteRepository останется в памяти на время существования контейнера, т. Е. На время существования веб-приложения, поскольку он является одноэлементным.Если в хранилище соединение с БД остается открытым, значит, это соединение останется открытым в течение того же времени жизни.
По этой причине альтернативным образом жизни является веб-запрос - другими словами, контейнер будет создавать новый экземпляр вашего класса SiteInfo один раз за веб-запрос.Стиль жизни для каждого веб-запроса обсуждается в другом вопросе .