#c# #validation
Вопрос:
В C# (ASP.NET Ядро), я часто использую шаблон опций:
public class FooConfig
{
[Required]
public string MyString { get; set; }
}
public class Foo
{
private readonly FooConfig _config;
public Foo(IOptions<FooConfig> options)
{
_config = options?.Value ?? throw new ArgumentNullException(nameof(options));
}
public void DoSomething()
{
// Use _config.MyString here, e.g.:
Console.WriteLine("MyString starts with: " _config.MyString[0]);
}
}
Когда я использую значения конфигурации, могу ли я предположить, что атрибуты были проверены? Например, могу ли я предположить, что MyString
они не пусты? Или лучше добавить дополнительные проверки, как это:
public void DoSomething()
{
if (string.IsNullOrEmpty(_config.MyString))
{
throw [...];
}
Console.WriteLine("MyString starts with: " _config.MyString[0]);
}
Обычно я добавляю проверку при привязке параметров при запуске приложения. Однако Foo
класс ничего не знает о запуске, поэтому кажется неправильным делать предположения о проверке Foo
.
services.AddOptions<FooConfig>()
.Bind(Configuration.GetSection("Foo"))
.ValidateDataAnnotations();
Комментарии:
1. Это задокументировано здесь: docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/…
2. Я прочитал этот раздел. Означает ли это, что правильно, что
Foo
должен быть прямой доступ_config.MyString[0]
без проверкиnull
или непустой? Мне кажется нелогичным, чтоFoo
можно делать такие предположения, поскольку проверка включена / отключена в совершенно другом месте (при запуске).3. Похоже, вы философски беспокоитесь о том, должно ли что-то делать что-то другое или нет. Если это делает вас счастливыми, проверьте себя и не используйте проверку параметров
4. Это имеет смысл для кода, который я использую. Но что, если Foo / FooConfig является частью библиотеки, используемой многими различными приложениями? У некоторых из них может быть включена проверка, у других-нет. Ожидают ли пользователи, что класс проверяет свои собственные параметры?
5. @pschill Ничто в программном обеспечении не предсказуемо, всегда защищайся.
Ответ №1:
Foo
можете делать любые предположения, которые вам удобны, — это ваш код. Как прокомментировал Эрмия, «всегда будьте осторожны», и классы опций могут быть написаны несколькими способами, такими как вышеупомянутая проверка атрибутов или IValidateOptions
подход, класс опций, предоставляющий разумные значения по умолчанию, предоставляющий легкодоступный IsValid
метод или эквивалент или поощряющий регистрацию DI с помощью тщательно управляемого метода расширения.
Либо класс опций является вашим собственным, и в этом случае вы можете встроить в класс столько, сколько, по вашему мнению, требуется, и, следовательно, пропустить проверку по частям ниже по потоку, либо класс опций предоставляется внешним источником, находящимся вне вашего контроля. В этом случае, как и в любом стороннем коде, вы не должны ничему доверять: если вы вводите чужие классы опций, вам следует взять под контроль его проверку.ожидания вашего кода, либо путем проверки важных свойств перед их использованием, либо даже путем повторной реализации или расширения класса опций с помощью какой-либо оболочки, чтобы вы знали, что получаете именно то, что ожидаете.