После нескольких раз мне нужно реализовать шаблон Lazy<T>
, мне пришла в голову идея поместить весь шаблон в класс, чтобы скрыть Lazy-реализацию.Encapsulate Lazy <T>
В случае «Загрузка одноплодной объект конфигурации для моих услуг», я сделал что-то вроде этого:
public interface IConfigurationProvider<T>
{
T GetConfiguration();
}
public abstract class SingletonConfigurationProvider<TConfiguration> : IConfigurationProvider<TConfiguration>
{
private static readonly Lazy<TConfiguration> _lazy =
new Lazy<TConfiguration>(_loadConfiguration);
private static Func<TConfiguration> _loadConfiguration;
private SingletonConfigurationProvider() { }
public SingletonConfigurationProvider(Func<TConfiguration> LoadConfig)
{
_loadConfiguration = LoadConfig;
}
public TConfiguration GetConfiguration()
{
return _lazy.Value;
}
}
Моя цель состоит в получении от «внешнего» простоты в этом:
public class ConfigTest : SingletonConfigurationProvider<ObjectTest>
{
public ConfigTest()
: base(Load)
{
}
public static ObjectTest Load()
{
return new ObjectTest()
{
testInt = 3,
testString = "Hi"
};
}
}
точки являются:
- она компилирует, но он ломает во время выполнения, с «TypeInitialization Exceptio n "говорит, что
_loadConfiguration
не может быть пустым. Это потому, что ленивый строится до конструктораSingletonConfigurationProvider
? - Можно ли достичь того, чего я хочу, не нарушая семантики синглтона?
Вы в основном строите абстракцию вокруг двух строк кода: статическое поле и геттер. Это действительно стоит? – Sinatr
Проблема может быть в первой строке, где вы инициализируете _lazy, когда _loadConfiguration имеет значение NULL. Попробуйте переместить инициализацию в свой перегруженный конструктор. – Sarathy
@Sarathy В этом случае _lazy не может быть только для чтения –