Rules.Framework is a generic framework that allows defining and evaluating rules for complex business scenarios.
A rule is a data structure limited in time (date begin
and date end
), whose content is categorized by a content type
. Its applicability is constrained by conditions
, and a priority
value is used as untie criteria when there are multiple rules applicable.
By using rules, we're able to abstract a multiplicity of business scenarios through rules configurations, instead of heavy code developments. Rules enable a fast response to change and a better control of the business logic by the product owners.
Name | nuget.org | downloads | fuget.org |
---|---|---|---|
Rules.Framework | |||
Rules.Framework.Providers.MongoDB | |||
Rules.Framework.WebUI |
The Rules.Framework package contains the core of the rules engine. It includes an in-memory provider for the rules data source.
To set up a RulesEngine
, define the content types and condition types to be used.
enum ContentType { FreeSample = 1, ShippingCost = 2 }
enum ConditionType { ClientType = 1, Country = 2 }
Build the engine with the RulesEngineBuilder
.
var rulesEngine = RulesEngineBuilder.CreateRulesEngine()
.WithContentType<ContentType>()
.WithConditionType<ConditionType>()
.SetInMemoryDataSource()
.Configure(c => c.PriorityCriteria = PriorityCriterias.TopmostRuleWins)
.Build();
Use the RuleBuilder
to assemble a rule.
var ruleForPremiumFreeSample = RuleBuilder
.NewRule<ContentType, ConditionType>()
.WithName("Rule for perfume sample for premium clients.")
.WithContent(ContentType.FreeSample, "SmallPerfumeSample")
.WithCondition(ConditionType.ClientType, Operators.Equal, "Premium")
.WithDateBegin(new DateTime(2020, 01, 01))
.Build();
Add a rule to the engine with the AddRuleAsync()
.
rulesEngine.AddRuleAsync(ruleForPremiumFreeSample.Rule, RuleAddPriorityOption.ByPriorityNumber(1));
Get a matching rule by using the MatchOneAsync()
and passing a date and conditions.
var matchingRule = rulesEngine.MatchOneAsync(
ContentType.FreeSample,
new DateTime(2021, 12, 25),
new[]
{
new Condition<ConditionType>(ConditionType.ClientType, "Premium")
});
For a more thorough explanation of the Rules.Framework and all it enables, check the Wiki.
Check also the test scenarios and samples available within the source-code, to see more elaborated examples of its application.
To keep rules persisted in a MongoDB database, use the extension method in the Providers.MongoDB package to pass your MongoClient and MongoDbProviderSettings to the RulesEngineBuilder
.
var rulesEngine = RulesEngineBuilder.CreateRulesEngine()
.SetInMongoDBDataSource(mongoClient, mongoDbProviderSettings)
The WebUI package offers a way of visualizing the rules in your web service. To configure the UI, pass the rules engine as generic to the IApplicationBuilder
extension method provided.
app.UseRulesFrameworkWebUI(rulesEngine.CreateGenericEngine());
Access is done via the endpoint {host}/rules/index.html
.
The following list presents features already available and others planned:
- Rules evaluation (match one)
- Rules evaluation (match many)
- Rules content serialization
- Rules management (Create, Read, Update)
- In-memory data source support
- MongoDB data source support
- SQL Server data source support
- Rules data source caching
- Rules data source compilation
- WebUI for rules visualization
See the Wiki for full documentation, short examples and other information.
Contributions are more than welcome! Submit comments, issues or pull requests, we promise to keep an eye on them :)
Head over to CONTRIBUTING for further details.