На самом высоком уровне есть два способа контролировать, какие правила применяются (и даже рассматриваются):
- Загрузить все правила в сеанс и обработать их в рамках логики правил
- Загрузка групп правил в разные сеансы и наличие неких мета-правил, которые отправляют элемент управления в соответствующий поднабор правил.
Одним из упомянутых вами требований было следующее:даже не загружать правила, которые вам не нужны.Если это действительно так, я думаю, что вы находитесь прямо во второй группе решений.Движок не имеет встроенных механизмов, облегчающих этот сценарий, поэтому вам придется создавать его самостоятельно.На мой взгляд, вам понадобится набор мета-правил, загруженных в их собственный сеанс, которые вычисляют критерии, которые вы потом будете использовать для загрузки определенных правил.Например, у вас будет правило, которое соответствует транспортному средству, если оно является автомобилем, и вставляет тег «автомобиль» в сеанс.Некоторые другие мета-правила могут вычислять больше тегов.Затем вы будете использовать вычисленные теги для загрузки дополнительных наборов правил, например, загрузить все правила, которые имеют любой из этих вычисленных тегов, и скомпилировать их в отдельный сеанс, а затем выполнить ваши факты в соответствии с этими загруженными правилами.Правила должны быть скомпилированы и загружены в новый сеанс, потому что после компиляции фабрика сеансов является неизменной, поэтому новые правила не могут быть добавлены к ней.
Если вы можете ослабить свое требование не загружать всеправила, то у вас есть еще несколько вариантов.Вы уже затронули некоторые из вариантов в своем вопросе, но я думаю, что вам лучше всего использовать прямую цепочку для достижения того, чего вы хотите.Я лично думаю, что это лучше, чем пытаться динамически загружать и компилировать правила.
Например, у вас может быть правило, которое соответствует Транспортному средству, если это автомобиль, и выдает новый факт - Автомобиль, этот автомобиль.конкретные правила будут использовать позже:
Vehicle vehicle = null;
When()
.Match(() => vehicle, v => v.VehicleType == VehicleType.Car);
Then()
.Yield(_ => new Car(vehicle));
Тогда ваши правила, относящиеся к вашему автомобилю, будут выглядеть так:
Car car = null;
When()
.Match(() => car)
//...
Ни одно из правил, относящихся к автомобилю, даже не будет оцениваться, пока ваше правило не будетчто приводит к возгоранию фактов автомобиля.