21
Nov

Dynamic Data: The Little MetaModel That Could

When a MetaModel is initialized from a data source (via its respective provider), what additional information is determined in the process? The MetaModel itself contains a couple of useful instance properties and methods (more of which we’ll examine later), but for the purpose of this article, we only care about its Tables property, which is of type ReadOnlyCollection<MetaTable>. As you can imagine, that property returns a list of MetaTable instances that represent every entity in our underlying data source.

The MetaTable class contains a whole slew of useful properties that we otherwise couldn’t deduce from its respective model class, such as: ForeignKeyColumnNames, DisplayName, PrimaryKeyColumnNames and SortColumn. As you can see, because of the higher-level semantics provided us by the MetaModel, any controls within our UI, that are aware of the MetaModel, can now take advantage of these additional attributes. The MetaTable class also contains a Columns property, which is of type ReadOnlyCollection<MetaColumn>, and contains a list of every column/property in the entity.

The MetaColumn class is where the real meat of the metadata system lies. It contains loads of properties for gathering information about a column/property from its underlying model, such as: DefaultValue, IsGenerated, IsRequired, MaxLength, NullDisplayText and RequiredErrorMessage. In addition, a MetaColumn can be of type MetaChildColumn or MetaForeignKeyColumn if it participates in an association.

Why does any of this matter? Because this rich MetaModel, in conjunction with our actual data model, provides us with enough information about the structure/semantics of the data that we can begin deducing lots of functionality/behavior from it. Better yet, our UI can do that for us. It’s clear at this point that the only thing we need in order to begin developing smarter data-centric applications are UI frameworks that can understand and react to the contents of our MetaModel.

Before we move on to examining how Dynamic Data provides extensions to ASP.NET that allow our UI to make use of a MetaModel, we need to briefly address where the MetaModel is getting its contents from. How exactly does it know what the DefaultValue for a column is, or the DisplayName for an entity is? It simply asks the provider. If you’re using an Entity Data Model, its respective provider can scavenge metadata from the EDM; if you’re using a LINQ To SQL model, its respective provider can examine the MetaModel (yes L2S uses this term as well) for metadata; if you’re using any other datasource, then you can create a custom provider that can determine that information however it makes sense.

You may be thinking right now that neither an EDM nor a L2S model provide the full extent of metadata that I’ve highlighted our MetaModel as exposing, and you’d be exactly right. In addition to the providers looking at their datasource specific mediums for metadata, there is also a set of common data annotations that can be applied to your data model and will be picked up by the MetaModel. These annotations live in the System.ComponentModel.DataAnnotations assembly/namespace.

These annotations have absolutely nothing to do with Dynamic Data, and are meant solely for annotating model classes within data-driven applications. Dynamic Data just happens to be the first UI framework (technically ASP.NET is) that understands them and makes use of them. In the next article I’ll explain how to make use of these annotations.

19
Nov

Dynamic Data: Models, MetaModels And Everything In Between

In the previous article, I mentioned that the existing data controls in WebForms aren’t very smart as regards to your data, but in all fairness, it isn’t really their fault. How is a GridView supposed to know that a property is required? How can a FormView know that a specific control should include regular expression validation? How can a DetailsView know that certain columns shouldn’t be displayed? Since those controls are completely agnostic as to the type of data they are bound to, there is no set of common assumptions they can make about their bound data in order to provide a richer set of UI behaviors.

It almost seems like what we need is some sort of meta-model, that provides additional semantics/metadata on top of our data model that our WebForms controls can leverage to make the desired assumptions. That way, we could bind any type of data to the controls, and they wouldn’t have to rely on any specific model type, but could rather use the meta-model to determine the additional actions it should (or shouldn’t) take. Because the meta-model would have a common form, the controls would only have to be aware of a single metadata system.

While having a common metadata representation is great, how can a meta-model be created based on every possible type of data? Obviously that wouldn’t be practical to have a single codebase that determined metadata from every data type. Rather, what we’d need is the ability to create a provider that was aware of a specific data type and could create a meta-model from it. This way, allowing a new data type to work with our common metadata system would be as easy as creating a new provider.

The solution described thus far is exactly what Dynamic Data provides. A common meta-model system for describing data models with a higher semantic that a UI can leverage to be smarter by default. Out of the box, it includes providers for LINQ-To-SQL and the Entity Framework (which is why it has gotten a reputation for working solely against databases), but nothing stops it from working against any other data source. In fact, prototypes already exist that have Dynamic Data working against an ADO.NET Data Service, as well as a SQL Data Service.

So what does the code look like for creating a meta-model from an existing data model?

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        var model = new MetaModel();
        model.RegisterContext(typeof(AdventureWorksContext));
    }
}

In that code sample, “AdventureWorksContext” is the name of my ObjectContext (a generated class used for working with an Entity Data Model). It could have also been a DataContext (a class used for working with a LINQ To SQL model), and the MetaModel would have been created just fine. This is because the RegisterContext method is aware of L2S and EF models and will created the necessary provider to fill the MetaModel. What if your data source is something other then a L2S or EF model? Then you can just pass an instance of your custom provider to the RegisterContext method.

var model = new MetaModel();
model.RegisterContext(new ArbitraryDataModelProvider());

Your provider would then be responsible for traversing your data source and retrieving the metadata that described it. The first MetaModel that you create is considered the default instance, and is stored in the static MetaModel.Default property. MetaModels can also be retreived by type using the MetaModel.GetModel method (in case you have multiple). Once you’ve created your MetaModel during your application’s start event in the Global.asax file, your MetaModel is now globally available throughout your application, just waiting to be leveraged by your UI.

While this all seems dandy, two questions arise: what metadata does the MetaModel expose, and where did it get it from? I’ll cover those questions in the next article.

19
Nov

Dynamic Data: Kickin’ It Old School

There have already been articles written illustrating how to leverage Dynamic Data within an existing web application, but instead of just outlining the steps required to do so, I’d like to give a little contextual explanation as to why you might want to do that, and what benefits may exist.

If you’re developing data-driven web applications with ASP.NET today then you’re already making use of the rich server-control offerings provided (e.g. GridView, ListView, *DataSource), and can attest to the productivity boosts gained (most of the time). What you lack though, when using the existing server-controls, is any notion of data-centricness. Your UI is completely stupid as regards to your data, and requires complete maintenance/upkeep whenever a change is made to your model, no matter how minute it is.

Imagine I’m using a GridView to provide an inline-editing tabular experience to my users. Within the GridView I configure the columns I want to display (or use AutoGenerateColumns), what each column’s header text is, what each column’s sort expression is, and what the primary key is (i.e. DataKeyNames). In addition, since I’m using the control’s inline-editing functionality I have to determine whether I want to allow certain columns to use the default TextBox rendering or provide a custom edit mode by creating a template. Even if I’m fine using the default edit mode provided by a BoundField, I might need to have some validation, which I won’t get out of the box, so I have to create a template. These decisions go on and on…

If you read through every requirement in the above paragraph, you may be thinking that some of that could easily be deduced from our data model (e.g. primary keys, required fields). I would go so far as to say that all of that, and more, should be easily deduced from our data model, and that is exactly the functionality that Dynamic Data provides. Dynamic Data provides the glue between your data model and your UI, making your UI able to automatically reflect model-level changes.

How does Dynamic Data provide that functionality exactly? Remember in the last article I mentioned that Dynamic Data is merely a set of extensions to ASP.NET, which means you don’t have to learn some completely new API, but rather a handful of new tools that work along with what you already know. From the perspective of adding data-centric functionality to an ASP.NET application, what we need in order to solve the problems outlined above, and what Dynamic Data provides us, can be broken down into three categories:

  1. Data-smart server controls
  2. Field templates for re-usable field-level UI
  3. Higher-level abstraction of our data model

Understanding why those three aspects are necessary and how Dynamic Data leverages them will make the goals of Dynamic Data much clearer. In the next article I’ll explain in detail how those three features can enhance the development of data-driven web applications.

17
Nov

Dynamic Data: Come For The Scaffolding, Stay For Everything Else

ASP.NET Dynamic Data has gotten a bad reputation for being nothing more than a new web application type that allows you to point at a database and get a fully generated site, complete with pages for working with the data in your database (CRUD operations). While that perception does hold some water, it is far from being the complete truth.

Then what is Dynamic Data? Well if you ask me…it is simply a set of extensions to ASP.NET that make developing data-centric applications easier. By “data”, I don’t mean database, I mean data of any kind. When those extensions are combined, they can provide you the scaffolding functionality mentioned above, but that is merely a side-effect of the entire suite of tools.

Viewing Dynamic Data as an application type doesn’t really make sense either as it is merely a complement to an existing web application. In its current v1 incarnation it can supplement WebForms, but work is already underway to bring data-centric functionality to ASP.NET MVC. Sure, there are project templates in Visual Studio for Dynamic Data, but instead of viewing them as a custom application type, look at it as a shortcut for a WebForms application that already has the entire Dynamic Data suite of extensions applied to it.

There are three points that I think are key to appreciating Dynamic Data’s applicability:

  1. It can be used within an existing application
  2. It can work against any type of data, not just relational
  3. Its metadata can come from anywhere, not just attributes on your data model

Once you’ve seen the above three points come to fruition, then you can begin to see Dynamic Data’s true colors. If then, you’re still not into it, then great, hate it for the right reason.

I’m going to put together a couple articles outlining the above three points in detail, as well as some screencasts that will show off some pretty interesting scenarios/implementations for leveraging Dynamic Data.

One final point that is important to notice is that the set of attributes that Dynamic Data leverages are not within the System.Web.DynamicData namespace, but rather the System.ComponentModel.DataAnnotations namespace. Why does that matter? Because it exemplifies the fact that those attributes are a common set of annotations for any type of data-driven application, with Dynamic Data being the first consumer. Who knows what kind of cool implementations will follow…

12
Nov

TechEd EMEA Presentations

Yesterday I gave two presentations in Barcelona at TechEd EMEA: Developing Data-Centric Web Applications and Introduction to ASP.NET MVC. I had a fair amount of requests for my decks, so I’m posting them up for all who care.

PowerPoint Decks:

1) Developing Data-Centric Web Applications

2)  Introduction to ASP.NET MVC

By far, my favorite part of both sessions was when I unveiled my new personal mascot: Giraffe Dog (G-Dog for short). This little guy will be accompanying me around all future presentations. Why you ask? Because he is just way too cool not to!

funny-giraffe-dog.jpg