Как правило, я избегаю синглетонов, потому что они затрудняют юнит-тестирование вашего приложения.Синглтоны сложно смоделировать для юнит-тестов именно из-за их природы - вы всегда получаете один и тот же, а не тот, который вы легко можете настроить для юнит-теста.Данные конфигурации - строго типизированные данные конфигурации, в любом случае - это одно исключение, которое я делаю.Обычно данные конфигурации в любом случае относительно статичны, и альтернатива включает в себя написание достаточного количества кода, чтобы избежать статических классов, которые фреймворк предоставляет для доступа к web.config в любом случае.
Существует несколько различных способов его использования, которыевсе еще позволит вам тестировать приложение.Один из способов (может быть, в обоих случаях, если ваш синглтон не читает лениво app.cofnig), это иметь файл app.config по умолчанию в вашем проекте модульных тестов, предоставляющий значения по умолчанию, необходимые для ваших тестов.Вы можете использовать отражение, чтобы заменить любые конкретные значения, необходимые для ваших юнит-тестов.Как правило, я настраиваю приватный метод, который позволяет удалять частный экземпляр синглтона при настройке теста, если я внесу изменения для определенных тестов.
Другой способ состоит в том, чтобы фактически не использовать синглтон напрямую, а создатьинтерфейс для него, который реализует класс singleton.Вы можете использовать ручную инъекцию интерфейса, по умолчанию к экземпляру singleton, если предоставленное значение равно нулю.Это позволяет вам создать фиктивный экземпляр, который вы можете передать тестируемому классу для своих тестов, но в своем реальном коде используйте экземпляр singleton.По сути, каждый класс, который нуждается в этом, поддерживает частную ссылку на экземпляр singleton и использует его.Мне нравится этот способ немного лучше, но поскольку синглтон будет создан, вам все равно может понадобиться файл app.config по умолчанию, если только все значения не загружены лениво.
public class Foo
{
private IAppConfiguration Configuration { get; set; }
public Foo() : this(null) { }
public Foo( IAppConfiguration config )
{
this.Configuration = config ?? AppConfiguration.Instance;
}
public void Bar()
{
var value = this.Config.SomeMaximum;
...
}
}