给定的规则集不包含类型为 System.Object、mscorlib、

The given ruleset does not contain any rules with type System.Object, mscorlib,

首先,我使用 www.codeeffects.com 框架来制作业务规则评估器,但在我的例子中,我需要类型是 100% 动态的。

我的概念验证方法中有以下代码。

public ActionResult Save(RuleModel ruleEditor)
{
    DummyEntitiesGen gen = new DummyEntitiesGen();
    Type t = gen.CreateType();
    List<dynamic> lista= gen.CreateTypeList();
    // At this point the rule model doesn't know which type to use as its source object
    // We need to "bind" the source type to the rule model
    ruleEditor.BindSource(t);

    // Add the rule model to the ViewBag object
    ViewBag.Rule = ruleEditor;

    // Make sure that the Rule Area is not empty and the current rule is valid
    if (ruleEditor.IsEmpty() || !ruleEditor.IsValid(StorageService.LoadRuleXml))
    {
        ViewBag.Message = "The rule is empty or invalid";
        return View("Index");
    }
    try
    {
        // Save the rule
        StorageService.SaveRule(
            ruleEditor.Id,
            ruleEditor.GetRuleXml(),
            ruleEditor.IsLoadedRuleOfEvalType == null ?
            true : (bool)ruleEditor.IsLoadedRuleOfEvalType);

        // Get all rules for Tool Bar and context menus and save it in the bag
        this.LoadMenuRules();

        DynamicEvaluator evaluator = new DynamicEvaluator(ruleEditor.GetRuleXml());               
        //bool success = evaluator.Evaluate(lista, ruleEditor.Id);

        IEnumerable<dynamic> result = lista.Filter<dynamic>(ruleEditor.GetRuleXml());
        //var result = lista.AsQueryable<t>().Filter(ruleEditor.GetRuleXml());

        ViewBag.Message = "The rule was saved successfully";
    }
    catch (Exception ex)
    {
        ViewBag.Message = ex.Message;
    }
    return View("Index");
}

对象列表很好,returns创建了一个我可以在调试时看到的动态类型列表。

然而,应该过滤的行给了我这个例外:

给定的规则集不包含类型为 System.Object 的任何规则,mscorlib

The GetRuleXml() method returns an XML with the type attribute set to a type of the source object. In your case it would be the name of the type returned by the gen.CreateType() method, e.g.:

<rule id='03b33dd0-4389-4ac4-a5aa-bd81fab41e00' eval='true' webrule='4.0.0.8' utc='10/20/2011 4:19:27 PM'
type='MyApplication.MyClass, MyApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab44223d08cca81e'>

During a compilation phase the engine checks the type of an instance object against the one specified by the type attribute. If they do not match you get that exception ("The given ruleset does not contain any rules...").

You could avoid it by clearing or removing the type attribute. Doing so bypasses type check during compilation.

That said, the CodeEffects rule engine does not support dynamic objects or types. Not yet anyway.

The DynamicEvaluator is a legacy class which has nothing to do with dynamic objects or types. It builds a dictionary of evaluators for each type of an object that gets evaluated allowing to reuse the same rule for various types so long their properties and methods match.

Once you remove the type attribute from the rule element, you will get a different exception, most likely "System.ArgumentException: 'x' is not a member of type 'System.Object'".

This is because there is no such type as dynamic in .NET. Dynamic merely tells a compiler to skip type checking during compilation and adds some magic at 运行-time. However, underneath it is passed as Object.

The engine uses expressions to build a rule, not reflection. Since it is the Object in case of dynamic, it will fail to find any properties or methods used in the rule's XML.

There are plans to add support for dynamic objects (objects implementing IDynamicMetaObjectProvider), but I don't know the timeframe.