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