Is there a RulesCollection property in BusinessBase?

Is there a RulesCollection property in BusinessBase?

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


pvanroos posted on Tuesday, May 09, 2006

Hi guys,

Does anyone know how to iterate through the rules collection in a derived object from businessbase.  Now I realize there's a BrokenRulesCollection, but I want to be able to use the rules from an business object to assist in building more meaningful web UI at runtime.  Should I modify businessbase or just extend it with my own base class?

Any ideas? 

Thanks,

Paul

RockfordLhotka replied on Wednesday, May 10, 2006

One of the most difficult choices to make when building a framework is how to scope your objects.

The more objects that are public in scope, the more flexible and reusable the code becomes.

Conversely, the more objects that are public in scope the less flexible the framework becomes.

By carefully restricting which classes, methods, etc. I have made public in CSLA .NET I have been able to enhance and extend the framework over the past few years - with minimal impact on existing code. There are relatively few breaking changes from version 1.0 to 1.52, and yet I was able to make some pretty big and important changes and enhancements.

All this is a fancy way of explaining why the rules collection is not public Smile [:)]

I'm actually speaking at a patterns and practices summit this week, so I've asked some fellow OO speakers and experts to get their thoughts on this. The challenge is that anything I make public becomes unchangeable (at least without great pain). The more I keep non-public the greater my ability to change the framework over time.

Yet you need to get at this information - which is also totally valid. So you can either alter the framework (which is costly, but workable). Or you could use reflection to tap into the non-public objects that already exist. In this second case, I'd recommend you create a "wrapper" or facade object that exposes the data the way you want, but uses reflection behind the scenes.

The value to this approach is that you get what you need, but yet it is very clear to both you and I that I am not committing to the way the rule list is currently implemented in CSLA. Which is good, because I hope to change the implementation at some point, as there are some features people would like to have (short-circuiting, prioritization, etc.) that I think are great ideas.

pvanroos replied on Wednesday, May 10, 2006

Hi Rocky,

Thanks for the reponse.  I realize you touched on this in your book, but I wanted to throw it out there one more time.  I toyed with the idea of modifying the framework (sacrilegious!), but I decided against it for many reasons (as you stated above).  At the end of the day with project deadlines fast approaching, I try to remain practical rather than philosophical.  ;-)  I'll create the wrapper.

Thanks for a great framework,

Paul

SoftwareArchitect replied on Thursday, May 11, 2006

Don't know if anyone else would (I suspect so), but I would love to see the wrapper when you have it working...if you were willing to share. 

I think it would take me a fair amount of time to re-invent your wheel but I have to have this functionality too.

Thanks,
Mike

RockfordLhotka replied on Thursday, May 11, 2006

So this is interesting I think. Given the literally infinite number of rule methods and rulearg subclasses that could exist, I am left wondering what such a rulescollection property would expose? Do you want to know the names of the rule methods? The type of the delegate (which is RuleHandler, so maybe that's no so useful)? I would guess the name of the property to which it applies - or perhaps it should be called GetRules() and should accept the property name as a paramter?

I am not adverse to adding something like this someday, but it wasn't clear to me what the interface should be and I didn't have time to give it enough thought to be meaningful. It still isn't entirely clear to me what info should be exposed to make this truly useful to a UI developer. At least not in an easy way.

To get at a lot of info you'd have to have access to the ruleargs object, and then decipher its meaning on a case-by case basis. That sounds like really tight coupling to me - a fragility problem. It would be nice to have a more abtract way of exposing the rules and their details perhaps?

In any case, I too will be interested to see what the wrapper looks like for input into this discussion.

Thanks, Rocky

RcHarvey replied on Thursday, May 11, 2006

How about....instead of creating a wrapper that uses reflection, inheriting and exposing the private member through a different method call?  I would think this would allow you to use the needed functionality without the overhead of reflecting through the object.

But, I am a novice at this.  So, my idea may not be very smart.

RockfordLhotka replied on Friday, May 12, 2006

That would be a good idea, except that I didn't make the low-level objects that store the details about validation rules protected either. They are internal/Friend in scope, and thus aren't visible even to a subclass. Really the only way to get at them is through reflection just at the moment.

glenntoy replied on Monday, May 15, 2006

Hmmm. I just read this thread. ;-) Aside from giving a meaningful web UI, could you guys site another set of examples and scenarios why RulesCollection is needed in BusinessBase?

Right now, I can't see the use of RulesCollection in BusinessBase? Enlighten me please..

Cheers,

Glenn

RockfordLhotka replied on Monday, May 15, 2006

I think there's potential value in a Windows UI too - as an example, some people like to set the max length property on a TextBox control to prevent the user from even trying to enter a value that's too long. So being able to find out, from the object, what that max length value actually is, would be useful.

In short, I understand the value - I'm just not sure how to expose the data in a way that's truly meaningful given that everyone can (and will) create their own validation rule methods. So I'm not sure how to distill that infinite variety down into something that would be useful to a UI developer (at least with reasonable ease).

david.wendelken replied on Thursday, June 15, 2006

glenntoy:

Hmmm. I just read this thread. ;-) Aside from giving a meaningful web UI, could you guys site another set of examples and scenarios why RulesCollection is needed in BusinessBase?

System Documentation Generation:  What business rules are in an object?

User Manual Generation: What business rules are in an object?

Test Plan Preparation: What business rules are in an object that I could test?

Requirements Traceability:  What rules in the code implement which system requirements?   This is particularly handy to have in the next example:

Legal Review: I just read that some jury awarded $500 million to a plaintiff, and I need to know what business rules I have in my system that might leave me open to a similar legal judgment!  (Or - hopefully - which ones will protect me... )

User Training: **I** think I should be allowed to do this, and the system won't let me.  Why is this a rule?  (Assumes traceability of a rule implementation back to business policies which trace back to achieving business objectives or mitigating business risks.)

A really good primer on Business Rules-based analysis is "Business Rule Concepts" by Ronald Ross. (www.brsolutions.com)

david wendelken

 

 

 

 

david.wendelken replied on Thursday, June 15, 2006

ps: the same thing is true for authorization rules, particularly in the USA with the Sarbanes-Oxley act.

rasupit replied on Friday, June 16, 2006

Unless I'm missing something, but aren't all of these are documented on your spec?  Why do you need to dig these out of the code. 

I would think that an application is build based on spec where it contain clearly defined use cases and business rules.

Ricky

david.wendelken replied on Friday, June 16, 2006

rasupit:

Unless I'm missing something, but aren't all of these are documented on your spec?  Why do you need to dig these out of the code. 

I would think that an application is build based on spec where it contain clearly defined use cases and business rules.

1) Specs are often this detailed:  "Go do it.  Hurry!"  If I'm not running the project, I don't get to control the quality of the spec or the time alloted for my assigned task, only the quality of the work I perform and the quality of its documentation.  This would cut down on the time it takes to prepare that documentation. 

2) In a team larger than me, it's a treat to have a programmer I trust to faithfully and doggedly follow a detailed spec.    On a bad day, when I didn't get enough sleep, I don't trust me! :)   This would enable me to automatically verify that they at least *started* coding the rule.

3) Even the programmers I trust to do a solid professional job are only human, they make mistakes too.  This would allow me to automatically catch that they forgot a rule without having to invest any appreciable amount of my scarce project management time to do it. (Or if I'm the programmer, it would do the same for me! :)

4) If I actually have a detailed spec and a contract that says I have to meet it, this would enable me to programmatically verify that I did include 1 rule function per spec.  (Testing would have to verify that the rules work as intended.)  It would also enable me, if I'm clever about how the test code is  created, to programmatically verify that I have at least one test per rule.

5) System design specifications are not user manuals or online help manuals.  I should generate those documents from the code instead of from the specification.    Why?  Because if some other programmer maintains the program before I get back to it, I can't trust that they maintained the specification also.  Or the user manual, for that matter.  The code is the ultimate arbiter of what the system actually does, the specification is the arbiter of what the system was supposed to do (at the time the spec was last updated). 

6) For the online help or user manuals, I can "dig" this information out of the code or I can load the information into the online help system by hand, or I could automate getting it out of the specification.  Of course, if I'm not the analyst on the project, I can't control the quality or format of the specification, so automating from the specification isn't a likely option.

7) I'm more likely to satisfy a Sarbanes-Oxley auditor of the system if the rules and authorizations are pulled directly from the code instead of from a specification.  It's more authoritative that way.

RockfordLhotka replied on Friday, June 16, 2006

Given these last few posts, I would suggest that the answer is to load the rules (validation and authorization) from a database, rather than hard-coding the relationships. That way you can report against a database rather than trying to report against code - which seems much easier.

One primary reason I implemented the rules functionality the way I did was to enable loading the rules dynamically rather than coding them statically. I can't say I did this for reporting - it was for manageability - but it would seem to address the reporting need as well...

david.wendelken replied on Tuesday, June 27, 2006

Loading authorization rules from the database seems to be a very straightforward task.  The basic data is generally very simple (you can or you can't), all you need is a list of properties and a list of methods or tasks.  I'm sure that there are folks that have more complicated scenarios, but that should suffice for most apps.    Generic code could easily handle this.

Doing the same for all validation rules does not seem so easy.  Generic code cannot handle all the rules in a typical application, some have to be manually coded.  A data structure that could define all possible (or likely) business rules is a non-trivial task.  That leaves us with maintaining information (the details about a rule) in two places - code and in the database.  That's double work and prone to human error. 

Some ideas that come to mind would be:

Seems simpler by far to do it the last way as part of the framework, but I would welcome other suggestions that would make some other way simple and not labor intensive!

 

 

RockfordLhotka replied on Tuesday, June 27, 2006

I think you overstate the complexity a bit, but you are essentially correct: you do need to hand-code non-generic rules, or rules that are custom to your application or business.

However, documenting such rules isn't really that unrealistic, nor is loading the association between rules and properties unrealistic. Remember, every rule method has to conform to the RuleHandler delegate signature, and you can adopt a standard by which every custom RuleArgs subclass must provide a documented, parameterized constructor. If you find XML comments too hard to deal with, you can use description attributes on the constructor's parameters to provide detail.

Using method metadata, you can then document rule methods by name. You can also envision a relatively straightforward (if loosely typed) model that can describe any RuleMethod:

  1. Assembly name
  2. Type name
  3. Method name
  4. RuleArgs type name (optional)
  5. RuleArgs parameters (optional) as a list of values (comma-separated strings, array of object, etc. The only requirement is that you can do generic parsing of the values by using Type.Parse())

This data is all you need to generate a delegate pointer to the specified method and create the specified RuleArgs. Couple this structure with a list of assembly/type/property data for your business objects and you can load the rule relationships dynamically.

You can also infer a great deal of documentation from this - especially if you couple it with documentation (via XML or attributes) from the rule method and RuleArgs constructor parameters.

The end result is that your database and code provide the basis for automated documentation, and you can probably see how you might create a really cool admin tool to allow association of rules with properties.

The only thing you can't do with what I just described is create custom rules - you still need to write some code by hand. Smile [:)]

 

Of course even that can be overcome. There is an XML standard for describing rules. If you write a parser for that and use Reflection.Emit() you can dynamically create rule methods. Especially in .NET 2.0, where you can create "global static methods" using Reflection.Emit() - methods that don't belong to a class as such, but are just there, in memory, waiting to be associated with properties.

Copyright (c) Marimer LLC