Feedback on approach

Feedback on approach

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


ChristianPena posted on Monday, October 16, 2006

Hello,

We are currently ramping up to use CSLA on a rewrite of an application here at work. While thinking through our requirements, we started thinking about how we can lower our maintenance time. One issue that came to mind was the columns displayed in our ReadOnlyListBase views. These columns can be easily hidden if the user decides they want that, but it is a more involved change if the user wants to add new columns. We would have to change the stored procedure and ReadOnly object definition to match the new requirements.

We have designed a new class to meet this specific need: DynamicInfo. This class is a ReadOnly object that has properties indexed by a string index and can be bound to a grid through custom databinding. This is different from the typical approach to ReadOnly objects in that the DyamicInfo class does not have any hardcoded properties. The object will be populated by the results of a query or stored procedure. If the user wants to see new columns in the grid, then we just have to change the source data to meet the need.

The DynamicInfo class will have behavior like any other ReadOnly class. It can assume that some specific columns will be returned but any other columns not related to the behavior of the object are purely to meet the users needs. For example, it can be assumed that "Contact ID" will always be returned as it is important for the behavior of the class. On the other hand, "Nickname" will be returned only if user wishes to see that column.

I have attached the necessary classes and sample class here (with my manager's permission) in order to get feedback on the concept as well as to contribute to the CSLA community. This implementation is a proof of concept and will be improved if the idea seems viable. Any feedback on the concept or approach is appreciated. We will

Thank you,

Christian

Fintanv replied on Monday, October 16, 2006

We did something similar to this based on some work we found at CodeProject.  It has worked well for us, except when it comes to wanting to display hierarchical data.  In this case you have to be careful since it is the root bound class that gets queried for the property descriptors of all the child collections.  This means that it needs to know what properties each of its contained child collections, will hold.

Cheers,

Fintan

ChristianPena replied on Monday, October 16, 2006

Fintan,

Thanks for the reply. That is a good thing to note. I am not sure that we will be displaying hierarchical data in a grid so in our case it may not be an issue, but I will keep it in mind.

Have you found that you have saved yourself any work by taking this approach?

Thank you,

Christian

JoeFallon1 replied on Monday, October 16, 2006

Interesting idea.

How much testing/progress have you made on it?

Does it work?

Is it saving you time and effort?

How would you handle modifying the AuthorizationRules if you added a new column to the source query?

       'AuthorizationRules.AllowRead("ServAcctNo", "ServiceAccountInfoReadGroup")

 

Joe

ChristianPena replied on Monday, October 16, 2006

Joe,

This was implemented last week so I have not done extensive testing. It works in the sense that it binds to the grid that I am using. I am seeing some strange behavior in that an integer column is being bound to a checkbox. I haven't yet investigated why that is.

It hasn't saved me any time or effort except in the theoretical/academic sense that I can change the columns displayed by changing the stored procedure.

As for Authorization, I hadn't given it detailed thought yet, but I don't see why that wouldn't be database driven and so therefore dynamic as well. If I add a new column to a view, I could just as easily add the column to the groups that have permission to it. The only real issue is to take care in not throwing exceptions or handling them to return a null value or some other default value to indicate that the value could not be retrieved because of Authorization reasons.

Thank you,

Christian

Kahn replied on Monday, October 23, 2006

Please keep us updated on this as I want to use something like thiis for a reporting kind of tool. i.e. rendering a DevX grid to look like a report and make it dynamic so that users can hide and add columns as they wish...However, I want to take it a bit further...and that is filtering dynamically...Any implementation details on this?

Thanks for posting your idea :)

Bayu replied on Monday, October 23, 2006

Hi Christian,

Your DynamicInfo looks very much like an experiment we have conducted here as well. Like you we found that many of the maintenance tasks were related to these kinds of minor changes, column additions/removals/renames and the likes.

Our experiment went one step further than your DynamicInfo in the sense that we also implemented a DynamicBusinessObject, i.e.: the editable complement that allows for the CRUD operations. We got it to work just fine, but in the end we ditched it.

Why?

Well, because:
- the 'dynamic' approach works great for business objects that simply serve as data containers
- but NOT for business objects that 'serve a use case' (this is an change of paradigm often mentioned on this forum, it means to not see BOs as data containers but as the servants of your use case).
- someone already mentioned things like authorization and validation, these are good examples of the use-case paradigm, but also think about scenarios where multiple BOs are orchestrated to fullfill a complex behavioral requirement (we had this with Order-related BOs which contain a LOT of constraints and logic)
- of course, you can make everything data-driven, it's easy to see how this could be accomplished for validation rules and authorization schemes. But when all your business objects are dynamic, i.e. they are data-driven, you will find that ALL your business logic needs to be data driven as well .... and that's simply too much (undebuggable, enormous administrative overhead, unmaintainable, etc) and in the end you are further away from your goal then when you started.

So we did something else:
- the core part of our BOs are codegen-ed, this involves at least all dataportal_xxx functionality, stored procs and business properties, so adding/removing columns is a no-brainer
- and we made all our data management related UI views dynamic ....


This last thing, dynamic UIs, made all the difference, we implemented 2  views one for displaying editable lists and one for displaying a single editable object. Both views can be rendered 'read-only' and 'editable' and fully support all validation and authorization stuff. They are fully dynamic, i.e. they can edit any CSLA-object. It took some time to get it right, but using one custom attribute and some reflection it is actually quite straightforward.

In sum:
- dymamic BOs will preclude support for complex use cases, which is the opposite of where they are intended for
- using codegen though, maintenance can be made easy on the and BO-level and below
- by making use of dynamic UI-views most of the changes made during maintenance tasks have no repercussions on the UI-level

Just my experience in an attempt to broaden the number of viewpoints in this discussion. Let us know what your final decision will be, I'm very much interested in this topic.

Cheers!
Bayu



Blarm replied on Monday, October 23, 2006

Christian,

This is something that I have been thinking about, but taking it a bit further.

In every application there are the 'master file'/maintenance tables, like the name/value list and similar tables with a few more columns. You can look at the table design and visiualise exactly what the business object code will look like. For these simple objects where the business object maps directly to the database table, I was thinking about having one business object that when created you would set the TableName, Primary Key Column and Primary Key Value which would be used to dynamically create the SQL statement for the Fetch (e.g. "SELECT * FROM tblNameValues WHERE ID = 1") .

The properties would then be populated as in your example (I was thinking of using XML rather than the dictionary). Also the CRUD methods would dynamically create the SQL statements at runtime.

As Bayu had rightly stated, this idea would be of no use where the business object  is anything other than a simple data container that maps directly to a databse table. However, for the simple case then I don't see the point of having several business objects gluttering up a project .

Unfortunately this is all just a thought at the moment and so I don't have any code to share.

Bill

 

 

ChristianPena replied on Monday, October 23, 2006

Kahn,

I am not sure that there is any filtering method inherent in this approach. You may have already seen the following thread, but I found it useful in drawing up ideas about how I can approach dynamic filtering:

http://forums.lhotka.net/forums/permalink/1024/1080/ShowThread.aspx#1080 

Bayu,

Thank you for the reply. I was hoping someone else had gone down this road and could shed some light on the experience ahead.

I see all of your concerns regarding this approach for a full Business Object. I agree that you are losing the sense of what the Business Object is supposed to be. If it is a full Business Object and it is completely dynamic, then it can have little or no behavior that makes it useful to you besides acting as a data container. For this reason, I am considering holding to the following rules when using this approach:

Blarm,

That is another viable approach. I had not considered storing XML, but I will certainly look at trying that approach. I was a little concerned with the weight of the dictionary per object. I was hoping to optimize the objects through the use of the Flyweight pattern, but I have not been able to get the implementation to a point where it is worth the trouble.

While I can sympathize with you on the issue of having too many files given a large number of use cases, I would argue that each instance required should have a class that wraps around your base dynamic class. I would do this in the interest of keeping the UI independent from the database layer. If in your UI code, you are instantiating a class by telling it what table and keys to use, then you are losing the buffering against data structure changes that you gain by using objects. Ultimately, there is no black or white when dealing with such issues, so please do share with us how you decide to approach the problem.

Thanks for your responses!

Christian

gdk9am replied on Tuesday, February 13, 2007

Hi

 

I am trying to developing a dynamic business object for All CRUD operations with

(a) dynamic properties

(b) dynamic business rules

(c) dynamic authorisation rules

Bayu, I am interesting how you handled dynamic properties when a new record is added ?

Copyright (c) Marimer LLC