Даже если есть 10 свойств, как вы говорите, если они требуются, и не имеет смысла давать им значения по умолчанию, я бы сказал, поместите их все в конструктор.
Если некоторые из них могут иметь разумные значения по умолчанию, вы можете оставить их вне конструктора и просто установить их по умолчанию.
Если ни одно из вышеперечисленного не является жизнеспособным, например, возможно, необходимо построить объект до того, как станут известны значения для этих свойств, тогда я бы посмотрел, имеет ли смысл передать требуемые свойства в качестве параметров методу (например, он либо не имеет много параметров, либо вряд ли будет вызван много раз, либо действительно реагирует на свое внутреннее состояние.)
За исключением всего вышесказанного, должно быть сгенерировано исключение. Кроме того, вы упоминаете "Бросить исключение и ожидать, что пользователь его поймает?" Назначение исключения не должно состоять в том, что вы ожидаете, что вызывающие его перехватят, вы должны ожидать, что они удостоверится, что свойство установлено. Поймать его следует в крайнем случае, когда они не могут разумно убедиться, что свойство установлено, и им все равно, если в результате ваш метод завершится неудачей.