With my previous post I’ve wrapped up an entire series where I talk about creating a dynamic DTO decorator, which started off as a way to leverage C#’s Dynamic Features to get rid of the need to implement INotifyPropertyChanged on every ViewModel and then morphed into decorating the object with some extra behavior (on the previous post, we’ve added support for some visual behavior).
As I mentioned many time in the series, the implementation I showed is a simplified version of something I had in a large Real World application. In this post I want to just mention some other things that were done in that application, to give you an idea on where else we can go with that approach.
There was a requirement where the application shipped with a database structure, but then it could be extended in production, based on each client’s needs. The clients couldn’t create completely arbitrary new data structures; instead, they’d create new tables which added columns to existing ones (a sort of inheritance).
The codebase had entities defined with the properties the application shipped with, but these entities also needed to be extended at the clients to support the columns they added to the tables in the database (they could only do this to very specific tables through the application).
In order to support that behavior, we created a DynamicEntity class, which followed the same approach of implementation as the DynamicDtoDecorator I’ve described on my series. The data access layer was responsible for setting things up so that NHibernate could work with the “dynamic” columns added to the tables. This layer would also dynamically add default values to certain properties on the entity, as specified by the end-users. The users could, for example, set the default value for a new property (new column in a table) by creating a expression such as x.PropertyA + x.PropertyB (where PropertyA may be one that ships with the application, while PropertyB may be a user-defined one).
Dynamic Business Logic
As the DynamicEntity travelled from the data access layer through the business layer, the framework added some special dynamic behavior as specified by users through the application. For example, the users could set range validation for properties on the entity (both for properties that shipped with the app, as well as those created by the client).
Dynamic Behavor for Presentation Layer
As the DynamicEntity reached the Presentation Layer, the framework added dynamic behavior related to presenting the entity to the user, such as handling what the background cell color should be for each property on the entity based on its value, whether a cell should be read-only, etc. Make sure to check out my previous post for an example of this.
From the database to the user interface
The framework provided an interface (IHandleRow, or something like that), which the different layers of the application (data access layer, business layer, presentation layer) could implement to inject the specific dynamic data and/or behavior the application needed on each layer. Since the end-users could override behavior shipped with the application, as well as add behavior to the columns they added, this approach using the C# Dynamic Features has helped tremendously in making an otherwise strongly-typed codebase support the business requirements.