65.9K
CodeProject 正在变化。 阅读更多。
Home

几分钟内在您的 ASP.NET 网站上实现复杂的业务规则

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (9投票s)

2011年7月5日

CPOL

20分钟阅读

viewsIcon

72050

downloadIcon

2206

本文介绍了一种在 ASP.NET 中编写业务规则的新方法,无需使用传统的决策表。

传统规则引擎(非常简要介绍)

如今,大多数应用程序都或多或少地实现了业务规则。其中大多数规则是静态的,意味着它们是代码的一部分,并且永不改变。

例如,考虑以下非常小的静态规则:

if(RightNow.IsDayTime) SetLightBackground();
else SetDarkBackground(); 

永远只有白天和黑夜。因此,除非该代码的业务所有者大幅更改 UI 要求,否则此代码将永远保持不变。此处不需要规则管理。

但是,如果一个公司有许多业务规则并且这些规则经常更改呢?以汽车保险费为例。计算保险费率的规则每月(甚至每天)更新。它们取决于驾驶员的年龄和性别、汽车的型号、行驶里程、年份、车身类型等。这些计算涉及大量变量。或者以任何大型 Web 表单为例,例如购物车,它会处理和验证用户提交的关键输入。此类表单的验证规则可能非常复杂,并且可能经常更改。

保险公司是否每次更新单个规则时都要编译、测试和部署其主应用程序?或者仅仅因为数据验证要求引入了微小更改,开发人员就需要部署新版本的 Web 应用程序?当然不是。他们使用业务规则引擎(BRE)——一种允许他们编写、测试和部署业务规则而无需重新编译整个代码库的软件。

规则基础(也非常简要介绍)

规则不过是方程的集合,通常按执行优先级分组到更大的规则集中。规则执行的最终结果可能是一个布尔值,指示成功或失败(评估型规则),或者在规则集成功执行后代码必须调用的某种操作(执行型规则)。我想说大约有十亿人会争辩说这个规则定义不正确/无效/不精确/不完整/不礼貌,但我认为它足以满足本文的需要。

任何规则的目的都是验证(或针对)某些数据。例如,汽车保险规则将针对申请保险的个人执行。代表该个人的对象包含作为其属性值的这些数据。该对象通常称为“fact”或“source”对象。简单规则的示例如下所示:

When
    Person.Age < 18
	Person.Car.Price > 100000.00
Then
	SetPremium(Standard + 50%)
Else
	SetPremium(Standard - Discount) 

在此示例中,Person 是该规则的源对象。

尽管上述示例看似简单的语法并不能完全说明问题。现实世界的规则通常不是那么初级。它们经常必须包含行内计算、调用外部数据源、声明和使用全局变量等。

规则引擎的要求

由于公司有不同的业务需求,它们通常有一系列非常具体的要求来编写和管理规则。但预计一个健壮的引擎至少必须提供以下内容:

  1. 它必须允许编写、测试和部署规则,而无需重新编译主代码。
  2. 它在执行规则时必须具有可接受的性能。
  3. 它必须允许以最少的信息技术部门参与来编写和管理规则。

第一点很棘手。有许多 BRE 不干扰基代码,但它们仍然期望规则作为本机对象(例如,C# 类)实现。在这样的引擎中,每次更新规则时都需要重新编译和重新部署规则。显然,对于这些引擎,您必须是程序员才能编写规则。这使得第 3 点几乎变得无关紧要。尽管如此,许多公司还是使用这类引擎,部分原因是拥有从内存运行的已编译规则可以提供性能优势,而无需采用复杂的缓存方案。当然,也有一些引擎可以接受文本规则,解析它并将其“注入”到代码中。它们通常声称拥有两全其美。

第 2 点只是枯燥。显然,所有引擎都说它们的性能非凡。它们都发布了非常有说服力的图表,清楚地概述了使用它们的解决方案与其他所有竞争对手相比的优势。所以,最后,您要么相信其中一个,要么运行他们的演示来亲自测试。

但第 3 点提出了一个问题,据我所知,这是 IT 决策者在选择 BRE 时绝对喜欢的问题:“使用您的引擎,一个典型的业务分析师能否在不学习任何额外知识的情况下创建和管理复杂的规则?”典型答案是“如果您的业务分析师可以遵循某些格式,那么是的,他们可以。通过使用决策表。”

为了快速说明什么是决策表,让我们考虑一个处理决策表的工作流程的高级描述:

  1. 业务人员根据特定的表格格式和规则(是的,是创建规则的规则)创建或更新规则。该格式和规则因引擎而异。规则作者将这些决策表保存为 Excel 电子表格、Word 文档、纯文本文件或 XML 文档,然后发送给 IT。
  2. IT 人员接收这些表格并将它们加载/部署到引擎中。通常,引擎是一个单独安装和维护的进程或一组进程,它“熟悉”规则存储的格式。它将规则转换为本机对象并做好准备。
  3. 当 fact/source 对象进入引擎时,引擎会找到适当的业务规则,并针对源对象执行该规则,将结果返回给主应用程序或调用特定的操作。

当然,还有批准更改、重新测试、调试、版本控制等问题。但让我们将这些讨论留给未来的文章,并回到这里的主要观点。

看!没有决策表!

在我们公司,我们与数十家大大小小的客户合作过。其中约 50% 使用各种 BRE——开源、商业或定制。除非它们的规则被编译或存储在数据库中,否则这些公司都会使用决策表。我们还没有发现一个客户在长远来看绝对满意。

问题在于,决策表自 20 世纪 60 年代以来就已存在,并且其概念在所有这些年里变化不大。它们确实很复杂。为了包含越来越多的功能,BRE 不得不扩展其格式。日益增长的业务期望也促成了这个过程。看看来自一个知名且广泛使用的开源 BRE 的决策表示例,此处。该文档坚持认为,需要至少两个人来编写决策表规则——“业务分析师”和“技术人员”。确实,仅仅通过查看该文档中的最后一个图像,就可以清楚地看出,普通业务用户在没有经过广泛培训的情况下根本无法编写业务规则。本文的目的是证明最后一个陈述是错误的。

我们从规则作者那里收到的第一个问题是:“我们能否**就这么输入我们说话的规则**,你们**将我们的输入翻译成有效的规则**?”几乎总是紧随其后的是问题 2:“我们能否在网上做到这一点?”借助我们即将探讨的新型规则引擎,我们终于可以回答这两个问题“是”。

让我们创建一个新的 ASP.NET Web 应用程序,并在几分钟内将其转换为一个功能齐全的业务规则引擎。为此,我们将使用一个名为 Web Rule 的新 ASP.NET 服务器控件。它支持 ASP.NET 3.5 及更高版本,并且只有一个小型程序集。在此处下载其免费版本

在我们开始之前,我认为我们需要完善要求:

  1. 规则编写必须集成到 Web 应用程序中,以便任何授权用户都可以从任何地方访问它。
  2. 在引擎集成到我们的 Web 应用程序并定义源对象之后,IT 人员无需参与即可创建、编辑、保存、加载、验证和执行规则。
  3. 已创建、验证和在线保存的规则可以被任何 .NET 进程传输到(或从)任何地方执行。
  4. 无需重新编译代码或进行任何类型的规则部署即可执行已保存的规则,无论执行发生在何处。
  5. 任何具有小学学历的人都能够创建和编辑复杂的业务规则。

听起来令人兴奋,同时又难以置信,对吧?请注意,此 Web 应用程序将没有规则版本控制、规则审批流程或基于角色的访问管理(但定义谁可以访问规则的规则可以使用此规则引擎构建!是的,我知道……)任何经验丰富的 Web 开发人员都可以在几周内使用常见的 ASP.NET 功能和组件在现有引擎之上构建这些功能。我们的主要目标是在线规则编写和执行,而无需决策表。

构建业务规则引擎

因为我们以汽车保险示例开始本文,所以让我们为汽车保险应用程序构建一个 BRE。让我换个说法:让我们构建一个**能够处理**任何业务规则的业务规则引擎,包括来自保险行业的规则。我从未在汽车保险业务工作过,所以我不知道他们的规则是什么样的。但这才是关键:让保险专家来创建这些规则!我们只需要提出一个代表虚构保险申请人的源对象。我们的 BRE 的结构将非常简单:

  • Web 应用程序将托管 Web Rule 控件,允许用户创建、验证、保存和编辑业务规则。我将使用 VS 2010 Web 应用程序项目模板,但您也可以使用网站。VS 2008 也可以。
  • 我们还需要一个源对象(C# 类)来表示我们的申请人。
  • 在现实生活中,典型的保险公司每天会收到数千甚至数百万份申请。为了处理这种负载,它们的规则执行将委托给一个单独的、始终在线的进程,可能是 Windows 服务,这些进程知道如何处理传入的源对象、如何加载规则以及如何针对接收到的数据执行这些规则。但在这里,我将只添加另一个执行所有这些操作的网页。虽然不是企业级的,但仍然具有教育意义。您将看到执行规则只需要 Web Rule 中的一行代码。因此,在本文的上下文中,无论该行在哪里执行,只要在技术上有效,就无关紧要。

那么,让我们开始吧(最终项目附加到本文中)

  1. 打开 Visual Studio 并创建一个名为 `CodeProject.WebRule.Site` 的新 Web 应用程序。如果尚未存在,请在应用程序根目录中添加一个新的 `Default.aspx` 页面。
  2. 引用下载的 `CodeEffects.Rule.dll` 程序集。为此,请在解决方案资源管理器中右键单击 Web 项目节点,选择“添加引用…”,单击“浏览”选项卡,导航到并选择 Web Rule 程序集,然后单击“确定”按钮。
  3. 向 Web 应用程序添加一个新类。该类将是我们的申请人源对象。请注意,我们可以在任何其他项目或库中声明它,并通过引用库的 DLL 来重用它。但在此情况下,我宁愿保持简单。因此,在解决方案资源管理器中右键单击项目,选择“添加 - 类…”,将其命名为 `Applicant.cs`,然后单击“确定”,让我们来谈谈源对象。

    在 Web Rule 中,源对象是您定义的 .NET 类型/类,用于保存业务数据并针对该数据执行规则。例如,当申请人向我们的虚构代理人申请保险时,代理人将创建一个 `Applicant` 类的实例,用申请人的数据(姓名、地址、汽车信息等)填充它,然后将此实例发送到某种队列以针对已由其他人使用我们的 Web 应用程序创建和保存的现有规则执行。

    如上所述,规则有两种类型:执行和评估。Web Rule 需要知道我们的 `Applicant` 将与哪种类型的规则一起使用。它还允许您使用位于 `CodeEffects.Rule.Attributes` 命名空间中的属性指定大量可选元数据。每个规则元素都有一个属性,然后还有一些。尽管我们将在文章后面讨论其中几个,但其范围限制了我无法提供更多详细信息。您可以在此处了解有关 Web Rule 属性和源对象自定义的所有信息。对于此项目,我们将创建执行类型规则,因为它们比评估类型规则更有趣。为此,我们必须用至少一个属性——`CodeEffects.Rule.Attributes.SourceAttribute`——来装饰我们的源对象,并将其 `RuleType` 属性设置为 `Execution`。我们还需要声明一些属性来定义我们的申请人和她的车辆。

    using System;
    using CodeEffects.Rule.Attributes;
    using CodeEffects.Rule.Common;
    
    namespace CodeProject.WebRule.Site
    {
    	[Source(RuleType.Execution)]
    	public class Applicant
    	{
    		public Applicant()
    		{
    			this.DOB = DateTime.MinValue;
    			this.Gender = Gender.Unknown;
    		}
    
    		public string Name { get; set; }
    		[Field(DisplayName = "Date of Birth", 
    				DateTimeFormat = "MMM dd, yyyy")]
    		public DateTime DOB { get; set; }
    		public Gender Gender { get; set; }
    		public decimal? Income { get; set; }
    		public decimal? Debt { get; set; }
    		public Address Home { get; set; }
    		public Address Work { get; set; }
    		public Vehicle Car { get; set; }
    		[ExcludeFromEvaluation]
    		public Policy Policy { get; set; }
    
    		public void Approve(Applicant applicant, decimal premium)
    		{
    			this.Report(applicant, true, premium);
    		}
    
    		public void Decline(Applicant applicant)
    		{
    			this.Report(applicant, false, 0);
    		}
    
    		private void Report(Applicant applicant, 
    				bool approved, decimal premium)
    		{
    			applicant.Policy = new Policy();
    			if (approved)
    			{
    				applicant.Policy.Approved = true;
    				applicant.Policy.Number = Guid.NewGuid();
    				applicant.Policy.Total = premium;
    			}
    		}
    	}
    
    	public class Address
    	{
    		public Address() { }
    
    		public string Street { get; set; }
    		public string City { get; set; }
    		public string Postal { get; set; }
    		public string State { get; set; }
    	}
    
    	public class Vehicle
    	{
    		public Vehicle()
    		{
    			this.Manufactured = DateTime.MinValue;
    			this.Engine = Engine.Unknown;
    			this.Turbo = false;
    		}
    
    		[Field(DisplayName = "????? ??????????", 
    			Max = 30, ValueInputType = ValueInputType.User)]
    		public string Brand { get; set; }
    		public DateTime Manufactured { get; set; }
    		public Engine Engine { get; set; }
    		public bool Turbo { get; set; }
    	}
    
    	public class Policy
    	{
    		public Policy()
    		{
    			this.Number = Guid.Empty;
    			this.Approved = false;
    			this.Total = 0;
    		}
    
    		public Guid Number { get; set; }
    		public bool Approved{get;set;}
    		public decimal Total { get; set; }
    	}
    
    	public enum Engine
    	{
    		Gasoline,
    		Diesel,
    		Hybrid,
    		[ExcludeFromEvaluation]
    		Unknown
    	}
    
    	public enum Gender
    	{
    		Male,
    		Female,
    		[ExcludeFromEvaluation]
    		Unknown
    	}
    } 

    Web Rule 将源对象的公共值类型属性转换为规则字段。但我有意在我们的源对象中添加了几个引用类型属性——Home、Work 和 Car,以证明 Web Rule 不仅限于值类型。当在网页上初始化时,Web Rule 会扫描引用类型的 `public` 属性,查找其内部值类型属性。它将找到的那些也用作规则字段。默认情况下,规则字段将在规则区域中显示其相应的属性名称。在我们的示例中,它将是 `Name`、`DOB`、`Home.Street`、`Work.City`、`Car.Brand` 等。对于更复杂的对象,字段可能看起来像 `Home.Phone.AreaCode` 或 `Atlanta.IT.Development.Web.FirstName`。您可以通过使用可选的 `Field` 属性来更改这些难看的名称(以及许多其他内容)。这在多语言环境中尤其有用。为了演示这一点,我用 `Field` 属性装饰了 `DOB` 和 `Vehicle.Brand` 属性,并设置了适合其类型的特定参数。

    您可以通过用 `ExcludeFromEvaluation` 属性装饰任何属性或方法来阻止任何属性或方法被用作规则元素。例如,我们不希望我们的保险分析师能够输入“未知”性别或发动机到规则中。我们也不希望他们能够使用 Policy 属性来制定规则。Policy 类型代表规则执行的结果,将由规则操作用于向系统报告。因此,我用 `ExcludeFromEvaluation` 属性将这些项目排除在规则的用户界面之外。

    执行类型规则需要操作。我声明了两个。任何返回 `void` 的 `public` 非 `static` 方法都可以是规则操作。它们可以声明在源对象内部或任何其他引用的 .NET 类(外部操作)中。操作可以是无参数的,或者它们可以接受值类型参数或源对象实例。与属性的 `Field` 属性一样,如果需要更改操作的名称(使其与默认值不同),请使用可选的 `Action` 或 `ExternalAction` 属性。可以使用 `ExcludeFromEvaluation` 来排除任何方法。在此示例中,`Approve` 和 `Decline` 方法将自动用作规则操作,因为它们都是返回 `void` 的 `public` 非 `static` 方法,并且它们都接受值类型和/或源对象类型的参数。但是 `Report` 方法被排除了,因为它是一个 `private` 方法。

    为了使代码示例尽可能易于阅读,我不会在所有属性和操作中都使用所有可能的属性。但您可以下载附加到本文的项目,并查看其中的源对象——它被装饰得像一棵圣诞树。非常有用的东西。

    定义了源对象后,让我们回到我们的 Web 应用程序。

  4. 打开我们之前创建的 `Default.aspx` 页面,并在 `@Page` 指令之后立即包含以下代码来注册 Web Rule 控件:
    <%@ Register Assembly="CodeEffects.Rule"
    	Namespace="CodeEffects.Rule" TagPrefix="rule" %> 
  5. 在页面中添加控件实例,并通过将以下声明放置在 HTML 标签内的任何位置,将我们的 `Applicant` 类设置为控件的源对象:
    <rule:AspControl ID="ruleControl" runat="server"
    	SourceAssembly="CodeProject.WebRule.Site"
    	SourceType="CodeProject.WebRule.Site.Applicant" /> 

    Web Rule 还有许多其他属性和方法可供您使用,以自定义您的引擎的工作方式,但我只设置了运行我们所需的最少值。信不信由你,**此时我们已经拥有了**运行此页面并**开始编写规则所需的一切**。我们还不能保存这些规则,也不能执行它们,但我们可以玩控件的用户界面来构建规则,这对某些人来说很有趣……至少对我认识的一些人来说:)

    顺便说一下,关于 Web Rule 的用户界面。要创建规则,只需单击规则区域内的任意位置,然后开始从上下文菜单中选择适当的项。这些菜单仅显示与您在规则中当前位置相关的项。每次需要调出菜单时按空格键。要导航出规则区域,只需单击其边界外的任何位置。您还可以通过插入制表符来缩进规则行。按 Enter 键插入新行或完成值输入。在您编写规则的过程中,阅读控件的“帮助字符串”中显示的“实时”说明。总的来说,它非常直观且有趣。并且它正在不断开发中,未来计划实现许多新的酷功能。

    通常,您会在数据库中保存规则,并从中提供规则以供执行。但是,当然,您并不局限于数据库。Web Rule 以 XML 格式输出规则,因此可以轻松地将它们存储在任何地方。为了简化此示例,让我们将规则存储在一个文件夹中作为 XML 文件。

  6. 在我们的应用程序根目录中添加一个新文件夹。在解决方案资源管理器中右键单击项目节点,选择“添加 - 新文件夹”,然后将其命名为 Common。按 Enter 键保存。
  7. 现在我们需要一个按钮。在控件下方声明它:
    <asp:Button ID="btnSave" runat="server" Text="Save" Width="100"  onclick="Save" /> 
  8. 在代码隐藏文件或 HTML 中包含按钮的“click”事件处理程序:
    protected void Save(object sender, EventArgs e)
    {
    	if (this.ruleTestControl.IsEmpty || !this.ruleTestControl.IsValid) return;
    	// Use .config extension to prevent IIS from serving this file
    	string file = Server.MapPath("/Common/Rule.config");
    	string rule = this.ruleTestControl.GetRuleXml();
    	System.IO.File.WriteAllText(file, rule);
    } 

    尽管此处理程序只有 4 行代码,但让我们详细讨论一下。显然,如果控件为空,则执行任何操作都没有意义,这意味着规则区域中没有输入任何规则。但处理程序第一行的第二个语句是最有趣的。Web Rule 内置了自动规则验证。此验证确保每条通过检查的规则都是有效的,并可以保存/测试/使用。除了检查控件的 `IsValid` 属性以调用验证外,无需编写任何额外代码。如果 Web Rule 检测到无效规则,它会停止进一步处理,在其帮助字符串中显示警告消息(如果已启用),并突出显示所有无效的规则元素。作者可以将鼠标悬停在每个无效元素上,以查看问题的详细描述。如果您使用的站点是其他语言,或者您不喜欢默认消息,您甚至可以覆盖这些默认描述。但同样,这超出了本文的范围,请参阅 Web Rule 文档了解更多信息。即使您在处理规则时忘记检查 `IsValid` 属性,如果规则无效且您的代码尝试读取它,Web Rule 也会抛出 `CodeEffects.Rule.Common.InvalidRuleException`。所以,这是一个非常健壮和优雅的解决方案。

    要查看此自动验证功能,只需运行到目前为止的代码(或访问 Web Rule 的演示页面)并尝试提交无效规则。这很有趣,我保证。

  9. 您还可以加载现有规则进行编辑。我们在页面的 `OnLoad` 处理程序中执行此操作:
    protected void Page_Load(object sender, EventArgs e)
    {
    	string file = Server.MapPath("/Common/Rule.config");
    	if (!this.IsPostBack && System.IO.File.Exists(file))
    		this.ruleTestControl.LoadRuleFile(file);
    } 

    加载现有规则只需要这么多。如果您将规则的 XML 保存到数据库中,加载它的代码也非常简单:

    protected void Page_Load(object sender, EventArgs e)
    {
    	if (!this.IsPostBack)
    	{
    		string xml = Database.GetRuleXML();
    		this.ruleTestControl.LoadRuleXml(xml);
    	}
    } 

    通过加载现有规则,作者可以修改它,并将新版本保存回服务器或数据库。此时,我们已经拥有了能够创建、保存和修改业务规则所需的一切。

    请注意,在我们构建 Web 应用程序并创建一种将规则保存到/检索自数据存储的方法之后,我们虚构的保险分析师就不再需要我们开发人员了。没有决策表,没有规则部署……是时候找新工作了?还没呢。我们还需要完成规则执行部分。然后我们就可以开始打扰招聘人员了:)

    执行本身只需要一行代码:

    CodeEffects.Rule.Evaluator.Execute(ruleXml, sourceObjectInstance); 

    通过调用此行,我们指示 Web Rule 在任何规则方程或方程组的计算结果为 `true` 时调用适当的操作。与其他安装自己执行进程的规则引擎不同,Web Rule 允许您调用其 `static Evaluator.Execute` 或 `Evaluator.Evaluate` 方法(分别用于执行和评估类型的规则),只要引用了 `CodeEffects.Rule.dll`。这意味着您可以管理任何 ASP.NET Web 应用程序或网站中的规则,并在**任何**新旧应用程序或进程中执行规则,无论是 Windows 服务、WPF、Silverlight、ASP.NET MVC、MSI 安装程序、代码库等。

    因此,如果我们的保险公司是真实的,规则将由一组业务分析师在一个 Web 应用程序中管理。这些规则将针对 `Applicant` 类的实例(可能是数百万个)执行,由完全独立的进程在公司网络上的某个地方持续运行,等待传入的申请人。我们显然无法在此文章中重现这种全局场景。相反,让我们再添加一个网页,通过单击按钮来执行我们的规则。

  10. 向项目添加一个新的 Web 窗体。在解决方案资源管理器中右键单击项目节点,选择“添加 - 新项…”,从模板列表中选择 WebForm,将其命名为 `Executor.aspx`,然后单击“确定”。
  11. 为了执行规则,我们不需要在页面上注册 Web Rule,只需要一个按钮、它的点击处理程序和一个用于显示结果的标签:
    <asp:Label ID="lblInfo" runat="server" />
    <br/><br/>
    <asp:Button ID="btnSave" runat="server" 
    	Text="Execute" Width="100" onclick="Execute" /> 
  12. 处理程序将创建一个 `Applicant` 类的实例,用测试数据填充它,并将它与我们之前创建并保存到 `/Common` 文件夹的规则 XML 一起传递给 `Evaluator` 类。然后它将检查 `Applicant` 的 `Policy` 属性,以查看我们的申请人是被拒绝还是被批准。
    protected void Execute(object sender, EventArgs e)
    {
    	Applicant applicant = new Applicant
    	{
    		Name = "Susan Doe",
    		DOB = DateTime.Now.AddYears(-25),
    		Gender = Gender.Female,
    		Income = 50000,
    		Debt = 10000
    	};
    	applicant.Car = new Vehicle
    	{
    		Brand = "Jeep",
    		Engine = Engine.Gasoline,
    		Manufactured = DateTime.Now.AddYears(-3),
    		Turbo = false
    	};
    	applicant.Home = new Address
    	{
    		City = "Alpharetta",
    		Postal = "30004",
    		State = "GA",
    		Street = "123 Main Street"
    	};
    	applicant.Work = new Address
    	{
    		City = "Atlanta",
    		Postal = "30315",
    		State = "GA",
    		Street = "987 Office Drive"
    	};
    
    	string rule = System.IO.File.ReadAllText(
    		Server.MapPath("/Common/Rule.config"),
    		System.Text.Encoding.UTF8);
    
    	CodeEffects.Rule.Evaluator.Execute(rule, applicant);
    
    	System.Text.StringBuilder sb =
    		new System.Text.StringBuilder("Application ");
    
    	if (applicant.Policy == null) sb.Append("errored.");
    	else
    	{
    		if (applicant.Policy.Approved)
    			sb
    				.Append("approved. Premium: ")
    				.Append(applicant.Policy.Total)
    				.Append(" USD, Policy ID: ")
    				.Append(applicant.Policy.Number);
    		else sb.Append("declined.");
    	}
    
    	this.lblInfo.Text = sb.ToString();
    } 

就这样。我们有了一个业务规则引擎。构建并运行项目。首先在 Default 页面上创建并保存一些规则。然后打开 Executor 页面并单击 Execute 按钮来执行该规则。

摘要

让我们总结一下我们所做的一切。我们构建了一个新的 Web 应用程序,该应用程序能够在无需 IT 干预的情况下管理复杂的业务规则。我们的规则编写用户界面干净直观。它是在线的,可以从任何地方访问。而且我们只花了几分钟就完成了。现在想象一下使用这种新的业务规则管理概念可以取得什么成就。

但不要认为规则引擎应该只被大型行业或政府使用。这不是关于它们——这是关于我们的。您可能已经在您的某个项目中拥有一个大型复杂的 Web 表单。该表单接受并验证大量用户输入。该表单对公司至关重要或非常重要,但您却大约每个月更改一次,因为那些……来自……部门的人似乎无法就其验证要求/策略/规则达成一致。停止捣鼓那个表单。在公司内部网上的某个地方使用 Web Rule 控件构建一个页面。在您的数据库中添加一个新表,其中包含 XML 或 `varchar(max)` 类型的列,并告诉页面将规则保存在那里。向您的……部门展示这个新页面。当他们兴奋地探索新的可能性时,注释掉现有的验证逻辑,并在您的表单中添加代码,该代码将从数据库中获取当前规则并针对用户输入执行它。就像我们在这里所做的那样。

编程愉快!

© . All rights reserved.