Вы можете написать конструктор, который найдет свойства типа 'string', существующие в вашем типе Configuration
, а затем перебрать эти свойства, пытаясь извлечь каждое из заданного словаря.Этот код даже может быть универсальным:
public T Build<T>(Dictionary<string, string> source)
where T : new()
{
var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty;
var properties = typeof(T).GetProperties(flags)
.Where(p => p.PropertyType == typeof(string));
var missingKeys = properties.Select(p => p.Name).Except(source.Keys);
if (missingKeys.Any())
throw new FooException($"These keys not found: {String.Join(", ", missingKeys)}");
var obj = new T();
foreach (var p in properties)
p.SetValue(obj, source[p.Name]);
return obj;
}
Использование:
// throws FooException if any key is missing
var config = Something.Build<Configuration>(dict);
Но обычно конфигурации не содержат строк.
- Что, если
Url
недействителен, uri? - Что если
Name
пусто? - Что если
Password
равно null
в словаре? - Что если некоторые числовые настройки не являются парсируемой строкой?И т.д.
Во всех этих случаях ваш код будет счастлив, и вы получите исключение во время выполнения.Все станет намного лучше, если вы будете использовать определенные типы для своих настроек string
, Uri
, int
, DateTime
и т. Д. И подтвердите эти значения, как только сможете.Также обычно некоторые параметры являются необязательными - вы не должны бросать, если этот параметр отсутствует в словаре или любом другом источнике, который вы используете.
public class Configuration
{
public string Name { get; set; }
public Uri Url { get; set; }
public int RequiredNumber { get; set; }
public int? NotRequiredNumber { get; set; }
}
Затем вы можете создать набор методов расширения, которые пытаются получать и анализировать значения изсловарь:
public static Uri GetUri(this Dictionary<string, string> source, string key)
{
if (!source.TryGetValue(key, out string value))
throw new ConfigurationException($"{key} not found");
if (!Uri.TryCreate(value, UriKind.Absolute, out Uri result))
throw new ConfigurationException($"{key} is not a valid uri: {value}");
return result;
}
И создание конфигурации будет выглядеть так:
var config = new Configuration {
Name = dict.GetString("Name"),
Url = dict.GetUri("Uri"),
RequiredNumber = dict.GetInt("RequiredNumber"),
NotRequiredNumber = dict.GetNullableInt("NotRequiredNumber")
};
Ваш код быстро потерпит неудачу в случае неправильной настройкиИ вы будете в полной безопасности, если будет создан конфиг.