Проверка параметров при запуске или в классе

#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 с помощью тщательно управляемого метода расширения.

Либо класс опций является вашим собственным, и в этом случае вы можете встроить в класс столько, сколько, по вашему мнению, требуется, и, следовательно, пропустить проверку по частям ниже по потоку, либо класс опций предоставляется внешним источником, находящимся вне вашего контроля. В этом случае, как и в любом стороннем коде, вы не должны ничему доверять: если вы вводите чужие классы опций, вам следует взять под контроль его проверку.ожидания вашего кода, либо путем проверки важных свойств перед их использованием, либо даже путем повторной реализации или расширения класса опций с помощью какой-либо оболочки, чтобы вы знали, что получаете именно то, что ожидаете.