3

First, I am using www.codeeffects.com framework to make a business rule evaluator, but in my case I need the types to be 100% dynamic.

I have the following code in my Proof of Concept method.

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");
}

the object lista is fine and returns a list of dynamic types created that I can see at debug time.

However the line that is supposed to filter is giving me this exception:

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

4

1 回答 1

2

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 run-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.

于 2016-06-17T19:59:10.637 回答