Skip to content

kdcllc/Bet.Extensions.Emet

Repository files navigation

Bet.Extensions.Emet

GitHub license Build status NuGet Nuget feedz.io

The second letter in the Hebrew alphabet is the ב bet/beit. Its meaning is "house". In the ancient pictographic Hebrew it was a symbol resembling a tent on a landscape.

Emet stands for truth in Hebrew.

Note: Pre-release packages are distributed via feedz.io.

Summary

The backbone of any business application is their complex business rules that applied to data.

This project is designed to provide with DotNetCore application with A Truth Engine for Business Rules.

The backbone of this library is RulesEngine designed by Microsoft team.

Read more on the design pattern by Martin Fowler

Features

buymeacoffee

Give a Star! ⭐

If you like or are using this project to learn or start your solution, please give it a star. Thanks!

Install

    dotnet add package Bet.Extensions.Emet

Usage

Sample Project

Bet.Extensions.Emet.WorkerSample - Console DI application with several workflows.

rules engine diagram

Steps

The follow is an example of including a workflow json file for validating country within provided input.

  1. Add Workflow to your project CountryWorkflow.json
[
  {
    "WorkflowName": "CountryWorkflow",
    "Rules": [
      {
        "RuleName": "Country",
        "SuccessEvent": "true",
        "ErrorMessage": "Country is not acceptable",
        "ErrorType": "Error",
        "localParams": [
          {
            "Name": "model2",
            "Expression": "\"india,usa,canada,France,China\""
          }
        ],
        "RuleExpressionType": "LambdaExpression",
        "Expression": "ExpressionUtils.CheckContains(input1.country, model2) == true"
      }
    ]
  }
]
  1. Add DI Registration
        public static IServiceCollection AddCountryWorkflow(this IServiceCollection services)
        {
            services.AddTransient<ICountryService>(
                    sp =>
                    {
                        var providers = sp.GetServices<IEmetProvider>().ToList();
                        var logger = sp.GetRequiredService<ILogger<CountryService>>();
                        var provider = providers.FirstOrDefault(x => x.Name == "CountryWorkflow");

                        return new CountryService(provider, logger);
                    });

            services.AddEmetProvider(
                    "CountryWorkflow",
                    reSettings: settings =>
                    {
                        settings.CustomTypes = new Type[] { typeof(ExpressionUtils) };
                    })
                    .AddFileLoader(configure: (options, sp) =>
                    {
                        options.FileNames = new List<string>{"Data/CountryWorkflow.json"};
                    });
            return services;
        }
  1. Create CountryService.cs
public class CountryService : ICountryService
    {
        private readonly IEmetProvider _provider;
        private readonly ILogger<CountryService> _logger;

        public CountryService(
            IEmetProvider provider,
            ILogger<CountryService> logger)
        {
            _provider = provider ?? throw new System.ArgumentNullException(nameof(provider));
            _logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
        }

        public async Task<bool> IsAcceptableAsync(string countryName, CancellationToken cancellationToken = default)
        {
            var engine = await _provider.RulesEngine.Value;

            var input = new
            {
                country = countryName
            };

            var results = await engine.ExecuteAllRulesAsync(_provider.Name, input);
            return results.FirstOrDefault()?.IsSuccess ?? false;
        }
    }
  1. Use it with your code
   var country = "Israel";
    var isValidCountry = await _countryService.IsAcceptableAsync(country);

    _logger.LogInformation("{country} is acceptable: {isValid}", country, isValidCountry);