我正在使用 NRules 来定义所有继承自一个公共基类的规则,该基类本身继承自Rule
.
当我使用 DSL 扩展插入包装匹配对象的新事实时,似乎传递给扩展方法的匹配对象是null
.
这是一个应该说明问题的独立示例。我正在使用xUnit
测试框架来定义两个规则,每个规则都有相同的测试。第一个通过,第二个失败。
using NRules;
using NRules.Fluent;
using NRules.Fluent.Dsl;
using Xunit;
using System.Linq;
using System.Reflection;
namespace IntegrationTests.Engine
{
// A simple domain model
public interface IFruit { }
public class Apple : IFruit { }
public class Basket
{
public Basket(IFruit apple)
{
MyApple = apple;
}
public IFruit MyApple { get; private set; }
}
// A base class for the rules
public abstract class RuleBase : Rule
{
public override void Define()
{
// Empty
}
}
// The first rule, which does not use the extension:
public class TestRule : RuleBase
{
public override void Define()
{
base.Define();
Apple a = null;
When()
.Match(() => a);
Then()
.Do(ctx => ctx.Insert(new Basket(a)));
}
}
// The second rule, which uses an extension to add a new fact
public class TestRuleWithExtension : RuleBase
{
public override void Define()
{
base.Define();
Apple apple = null;
When()
.Match(() => apple);
Then()
.AddToBasket(apple);
}
}
// The DSL extension
public static class DslExtensions
{
public static IRightHandSideExpression AddToBasket(this IRightHandSideExpression rhs, IFruit fruit)
{
return rhs.Do(ctx => ctx.Insert(new Basket(fruit)));
}
}
// The tests
public class ExtensionTest
{
// This one tests the first rule and passes
[Fact]
public void TestInsert()
{
//Load rules
var repository = new RuleRepository();
repository.Load(x => x
.From(Assembly.GetExecutingAssembly())
.Where(rule => rule.Name.EndsWith("TestRule")));
//Compile rules
var factory = repository.Compile();
//Create a working session
var session = factory.CreateSession();
//Load domain model
var apple = new Apple();
//Insert facts into rules engine's memory
session.Insert(apple);
//Start match/resolve/act cycle
session.Fire();
// Query for inserted facts
var bananas = session.Query<Basket>().FirstOrDefault();
// Assert that the rule has been applied
Assert.Equal(apple, bananas.MyApple);
}
// This one tests the second rule, and fails
[Fact]
public void TestInsertWithExtension()
{
//Load rules
var repository = new RuleRepository();
repository.Load(x => x
.From(Assembly.GetExecutingAssembly())
.Where(rule => rule.Name.EndsWith("TestRuleWithExtension")));
//Compile rules
var factory = repository.Compile();
//Create a working session
var session = factory.CreateSession();
//Load domain model
var apple = new Apple();
//Insert facts into rules engine's memory
session.Insert(apple);
//Start match/resolve/act cycle
session.Fire();
// Query for inserted facts
var bananas = session.Query<Basket>().FirstOrDefault();
// Assert that the rule has been applied
Assert.Equal(apple, bananas.MyApple);
}
}
}
问题是为什么带有 DSL 扩展的第二条规则不能正常工作?我做错了什么,我该如何解决?