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