Seeking Implementation Recommendation

Seeking Implementation Recommendation

Old forum URL: forums.lhotka.net/forums/t/5741.aspx


Jack posted on Wednesday, November 05, 2008

Hi,

Fairly new to CSLA and I'm hoping for a couple of tips for an implementation.

I have a dynamic data entry window that uses metadata on each input field (a row and editableChildBO) to define its rules.  Those rules are the simple min/max, length, set of values (dropdownList) but also include links to other values for calculated fields and logic to enable/disable other fields.

Anyhow many of theses fields are based on a template (i.e. all the items in a questionanaire are to be between 1 & 7 with the same text values associated with each value [1=red, 2=blue, etc]).

My plan is that I load the template business rules from the database and set those rules as Object rules and then I load each data field and link them to the appropriate template field.  That way I don't load the same template twice.

My long winded question is how to best trigger the business rule check on the template for each related data entry field.

Approach #1 seemed to tie in to the validation of the related template for each dataentry field but I can't see a simple spot to override a function or an event to tie in.  I also need to have the template almost reset for each iteration of validating the data fields.

My other thought Approach #2, was that as I link my data entry objects to their repective templates I iterate through the rules of the template and re-create them in each data entry field.  That creates separate encasuplated sets of rules but duplicates the rule objects.  I can have a hundred data entry fields all with the same set of rules so that is 100x as many rules as I need.  That seemed like a waste.

If these were not dynamic objects I would inherit each data entry field from its respective template and have duplicated sets of rules (#2) but simple implementation.

Before migrating this to CSLA the validation rules were part of the presentation layer.

Any thoughts?

thanks

jack

 

RockfordLhotka replied on Wednesday, November 05, 2008

The rule engine in CSLA breaks the problem into three parts:

  1. object property
  2. rule method
  3. connection of rule method to object property

Typically you'll have a library of rule methods, and the dynamic part of the system is connecting rule methods to object properties.

Normally this connection occurs in AddBusinessRules() and is done on a per-type basis. You can do this in AddInstanceBusinessRules() on a per-instance basis, so each object has a different set of rules.

Jack replied on Thursday, November 06, 2008

Rocky,

Thanks for the speedy reply - I am aware of how to 'connect' the rules and the option between per-type/per-instance.  I'm more interested in how to combine the two or if I should even bother.

So this would basically mean that my 100 child objects that share the same rules would instatiate all my dynamic rules 100x. 

Obviously the processing time has to exist, in order to check each rule 100x but should I care about the overhead of having the rules created or is it so negligable it doesn't matter.

This is a simple implementation, easy to debug etc.

Would I gain much by doing something along the lines of:

Create TemplateBO,

Create 100x dataField BO 

Link 100x dataFieldBO to TemplateBO

In validate of dataFieldBO push the datavalue (int, string, date) up to the TemplateBO and call validate.  Get BrokenRules.  Repeat 100x.

 

Thanks

jack

 

rsbaker0 replied on Thursday, November 06, 2008

^^^^

Why don't you run some tests to see if performance is an issue? I certainly wouldn't be concerned about it if you can go the per Type rules route, as this happens only once per Type. However, I can see how it might be an issue with per instance rules.

If you go the per type route, they are static for the duration of the application and there really isn't a good way to reset them.

 

Jack replied on Thursday, November 06, 2008

I wish I was so close to that point that I could do a test :-).  That's a ways off I think.  I keep plugging away and if someone with lots of experience suggests one over the other I'll start that way but likely I'll end up testing both or a 3rd idea if that comes up.

I think I'm also procrastinating on solving the design in lieu of just getting something done...

thanks

RockfordLhotka replied on Thursday, November 06, 2008

Per-type and per-instance rules can co-exist if that’s what you are asking?

 

There is overhead to using per-instance rules, and for a lot of objects it can add up. This is why per-type rules are the default.

 

But if you need customized lists of rules per-instance then it is hard to escape that overhead.

 

I think when you use the word “template” you really mean “business class”? So you are saying you could create a different class for each set of rules, and therefore could use per-type rules for each variation? I am sure that would work – the question is whether it is practical from a maintainability perspective.

 

You have made me think of something interesting though. CSLA stores the rules in a “rules set” that is indexed by object type. I suppose it would be possible to open that up so you could create a “rules set” based on an arbitrary key, and then associate an object instance with a specific rules set. This isn’t possible today, but is an interesting idea for a future version of the framework.

 

Rocky

 

Jack replied on Thursday, November 06, 2008

When I say Template I do mean a business class.

Just to clarify (which helps me think it out loade) in case it helps:

In my database I have a field table.  A field is really just a collection of metadata about a piece of information to be input.  It defines all the rules (min/max,not null, precision, display text, help text, etc).  I also have a templateFieldID which lets me link back to a master field so I can define most of the metadata once.

TemplateField = ID=0, IsTemplate=1, TypeNumber, Min1, Max5, NotNull, dropdownvalues('a','b'...) etc

TestField1 = ID=1, IsTemplate=0, TemplateID=0, <ignore most metadata>, Name=Score1

TestField2 = ID=2, IsTemplate=0, TemplateID=0, <ignore most metadata>, Name=Score2

Then I have a dataField tableset which contain the actual values for the data and all auditing info for each instance of data capture.

To do dataentry and implement my UI I have:

dataFieldBO for each dataTestFieldx which contains the value and all the UI logic around it (Missing data, auditing, etc) -> dataFieldxxx tables

Each dataFieldBO has a corresponding FieldBO which maps to the TestFieldx.  This has my rules. 

However the basic input rules are 90% in the TestScoreTemplate. So I also load from the database the distinct set of templateFields into my fieldBOList and then link all the objects together.  When a templateBO exists for a particular FieldBO then I'm passing control up the chain to get certain attributes.

Essentially I have 'inheritence' in the database for metadata rules that I am trying to reflect in the business rules.

I can't use perType rules as the set of TemplateFields is dynamic and the underlying dataFieldBO can all have different values to be validated by the same templateFieldBO. 

I did find this in the ChangeLog for 3.5 which would support the idea of having the TemplateFieldBO process some business rules and then return the brokenRulesCollection back to the FieldBO via a merge.

BrokenRulesCollection/BrokenRule (071127-VB/C#)

Add a CreateCollection() factory to allow creation of an empty BrokenRulesCollection. Add a Merge() method to allow other BrokenRulesCollections to be merged into this newly created list. As the BrokenRule objects are merged into the collection, the rule names are changed to be unique based on a “source” value. So a rule like rule://method/property becomes rule://source.method/property. Since you supply the source value, you can provide a meaningful value for each business object’s broken rules.

I think this supports the idea that in my pre-validation I have to push the value up to the linked templateFieldBO and process its validate routine.  If it is valid then I move along.  If not then I merge the templateFieldBO brokenrules to the dataFieldBO broken rules and keep going.  I basically have a set of rules indexed by key (templateFieldKeyID) with the overhead of a whole BO but I just need to manage setting the Property to be validated manually and make sure that validating FieldBO1 with the TemplateFieldBO doesn't impact FieldBO2 also linked to the same TemplateFieldBO.

What you suggested about bykey would be perfect.  You could have three sets of rules, Instance/Type/Unassociated and be able to link the validation logic to use the shared Unassociated rules based on a common or aliased propertyKey. 

Sorry for all the rambling... it does help my thought process though. 

Copyright (c) Marimer LLC