ASP.NET Dynamic Data is a technology in ASP.NET 3.5 and higher that attempts to solve the same problem as Peter’s Business Logic Driven UI (“BLD”). In fact, BLD’s origins were as an extension to Dynamic Data.
I wanted to get the controls of Peter’s Data Entry Suite into Field Templates of Dynamic Data and started on that before ASP.NET 3.5 shipped. Early on, I found the Field Template class required reworking in order to support the DES Validation Framework. It took off from there, where class by class, I found design problems or desired to do something different. That resulted in almost completely rewriting Dynamic Data. These days, BLD uses very little of Dynamic Data’s code. Almost everything has a different name. Only “Field Templates” and “Filter Templates” have survived, although without using the original code.
This process occurred over four years of iterative discovery and resolution. BLD would not have been built this way without these issues I determined are in Dynamic Data:
- The goal is to allow separating business logic from the user interface. However, it defines three key classes which describe the business logic within the user interface layer. Those classes are MetaModel, MetaTable, and MetaColumn. Explore any of them and you will find UI concepts within them, dealing with URL Routing.
BLD knows that there is a tremendous value having objects like these in the Business Logic Layer (“BLL”). The BLL should prepare and deliver a “MetaColumn” for the consumer to use. That allows the BLL to customize the business rules based on the current case, not the static metadata attached at compile time.
This data is also invaluable for your CRUD methods. For example, if you want write a query method that is passed filtering rules, those rules need to identify a specific column, and pass along data that is compatible with that column. The MetaColumn is a great description of the column, but is not allowed in a true BLL.
BLD has created its own classes replacing MetaModel, MetaTable, and MetaColumn. They are DataContextDescriptor, EntityDescriptor, and DataFieldDescriptor, they are defined in the BLL. BLD’s EntityFilter classes, which define filtering rules, are also elements of the BLL that are consumed by the UI to let the page visitor or Web Forms developer establish filters. These objects carry along a DataFieldDescriptor object.
- Dynamic Data fails to cover a significant part of the BLL: the Data Access Object (“DAO”) classes. These are where you define methods for CRUD actions based on your business rules. The most common rules are queries, such as a method called “SelectByPrice” in the Product’s DAO. Because of this omission and documentation built around using the LinqDataSource or EntityDataSource, the user ends of writing business logic for CRUD actions in the web form. That’s exactly what the user wanted to avoid!
If the user had realized this and created Data Access Object classes, they would still have to define a DataSource control that works with Dynamic Data. The ObjectDataSource control was intended for DAOs but was not built to support Dynamic Data.
BLD introduces its own Data Access Object classes and a supporting DataSource control. It also provides support for the user’s own Data Access Objects through the ObjectDataSource control.
- The Dynamic Data API has numerous members that are marked INTERNAL or PRIVATE, preventing their usage by its consumers, not to mention PROTECTED methods that are not marked VIRTUAL, preventing overriding them.
There is no way to use a subclass of something important like MetaColumn, where all of the business rules are listed, because even if you did subclass it, the code to instantiate a MetaColumn is hardwired into the MetaTable class, and not in a way that you could override. Peter encounterd wall after wall due to these API limitations as he attempted to create BLD.
BLD’s API assumes that users will want to subclass and replace its objects. It rarely uses INTERNAL members. PRIVATE is only used on field storage and special cases. Most PROTECTED methods are also virtualized. Finally, there is almost always a way to have your own class get instantiated, either by overriding a method where the original class was created, or through a factory.
- Validation is an essential business rule. When you add a ValidationAttribute (like RequiredAttribute or RangeAttribute) into your Entity class, you should not worry about updating the Field Templates to support it. Yet, that’s exactly what Dynamic Data does. Each Field Template requires that you add all possible Validator web controls and register it with the base FieldTemplate class. As you create new Field Templates, you have to be careful to cover all of them. If you create a new ValidationAttribute, you have to return to the Field Template files and update them. The user interface should never allow a validation business rule to be overlooked.
BLD resolves this by making all ValidationAttribute objects capable of creating the appropriate class used by the UI for its validation purposes. This should raise a red flag, because a BLL object creates a UI class, but BLD uses a factory to do this. It has the UI layer register all of its Validation classes, giving each type of validation rule a standard signature. So the author of a new ValidationAttribute simply requests the appropriate object from the factory. The identity of the UI layer is passed to the ValidationAttribute which is passed onto the factory.
The Field Template itself hosts a single control, BLDDataFieldValidators, which runs through the validation attributes for the column, asking each to create its validator.
- ASP.NET Dynamic Data does not appear to be prospering. Perhaps users don’t understand its value and perhaps those that do can not push it far enough to meet their needs. As a result, it makes little sense to deliver an improved Dynamic Data. Microsoft appears unlikely to grow it, addressing the issues already raised. So it’s best that BLD is not dependent on Dynamic Data.
While BLD is a different code base, Dynamic Data users will understand its user interface model. Every Dynamic Data control has an equivalent in BLD: DynamicControl is BLDDataField; DynamicDataManager is BLDPageManager; etc. The concepts of Page Templates, Field Templates, and Filter Templates remain, although they are coded differently.
If you have an existing Dynamic Data application, you cannot just rename the controls and start using BLD, but that’s probably a good thing since BLD makes so many improvements that often require doing things differently. Yet the most important control, DynamicControl, can usually be renamed to BLDDataField successfully. That allows the biggest piece of work on existing web pages – the content to show the user – migrates pretty easily.