Code or Configuration or Configuration in Code?

With DevOps bringing source control to configuration files and publishing to production servers being automated – bringing both code and configuration over on the same time, the difference between code and config has become less than ever (if it even exists).

A few weeks ago I reread Mike Hadlow’s brilliant post The Configuration Complexity Clock. As I’m also in the middle of setting up publishing routines for a web application I started to think about the difference between configuration and code. The more I think about it, the less clear the difference is.

A simple attempt to differentiate them would be to look at where they are stored.

  • Everything in source files that are consumed by the compiler is code.
  • Everything in configuration files that are read at runtime is configuration.

Unfortunately that is not the entire truth. For example the route config in an ASP.NET MVC application is a kind of configuration – but it is done in code. The same is true for the Entity Framework Code First mappings – it is done in code (either through attributes or a fluent API), but is a kind of mapping configuration. An example of the other way around is startup configuration scripts (think of *nix .bashrc or the old autoexec.bat on DOS systems). It is configuration, but is run as a script.

There are definitely cases where it is not that simple to define what is configuration and what is code.

And does it really matter?

EF Code First DbContext.SavingChanges

Unfortunately there is no SavingChanges event on the code first DbContext, but there is a way to get to it.

The DbContext used for data access with Entity Framework Code First has a simplified API compared to the ObjectContext which is good. Unfortunately it is a bit too simple sometimes. For example there is no built in event that can be used to act before pending changes are written to the database. Fortunately, there is a way to get to the underlying ObjectContext which has such an event.

[TestMethod]
public void TestSavingChanges()
{
    using (var ctx = new CarsContext())
    {
        var objCtx = ((IObjectContextAdapter)ctx).ObjectContext;

        bool eventCalled = false;

        objCtx.SavingChanges += (sender, args) => eventCalled = true;

        ctx.SaveChanges();

        Assert.IsTrue(eventCalled);
    }
}

Of course it would be really simple to create an own event inside an override of SaveChanges but having a built in one is even more simple. There is also a ObjectMaterialized event that is fired each time an object is loaded from the database as well as some additional methods and properties that are not available directly on the DbContext.

Separating the Read Model

A typical architecture of a .NET web application is to use EF Code First for data access and MVC to render the web pages. The data model in the database is usually (and should be!) normalized. A normalized data model is also great for updates, but when displaying data it is not enough. E.g. in a table of cars I don’t want to display a numeric, database internal id of the car’s brand. I want to display the name of the brand. Creating a separate read model simplifies that.

Separating the read and write models are a key concept of the recently popular CQRS (Command Query Responsibility Separation) architecture. I won’t go as far as the CQRS model does, but rather show a simple way to dress the write model’s car entity with the values required for displaying.

My key objective is to get a model where I can get everything needed for rendering a view to the user in one fetch from the database, with a minimum of extra coding and mapping code.

EF Code First/MVC NotNullAttribute

Unfortunately MVC3 doesn’t respect the [Required] attribute’s AllowEmptyStrings property. When using a class both as an MVC model and as an EF Code First entity this is a problem. What if I want to allow empty strings, but not null values in the database?

The problem lies in the client side validation performed by MVC3. If a property in the model is marked with [Required] the jquery required validator will be enabled. It requires a non-empty string. I would prefer MVC to not emit a required validation if AllowEmptyStrings is true. Unfortunately the MVC code doesn’t honor that flag, but there is a workaround. Create a small attribute derived from RequiredAttribute.

public sealed class NotNullAttribute : RequiredAttribute
{
    public NotNullAttribute()
    {
        AllowEmptyStrings = true;
    }
}

To make it work, another attribute has to be set on the property to prevent the model binder from converting an empty string to null.

[NotNull]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SomeProperty { get; set; }

It is surprisingly simple, but works thanks to a difference in how EF Code First and MVC3 handles attributes.

EF Code First Navigation Properties and Foreign Keys

An Entity Framework Code First class corresponding to a table with a foreign key typically has two fields for the foreign key. The foreign key as represented in the database and a C# reference.

[ForeignKey("BrandId")]
public Brand Brand { get; set; }
 
[ForeignKey("Brand")]
public int BrandId { get; set; }

This is a violation of the DRY principle. In C# there is nothing keeping the two properties in sync. We can set BrandId to the Id of Saab and the Brand reference to the Volvo object. If I do that, what will Entity Framework do when saving to the database? In this post I’ll investigate how Entity Framework handles the situation.

Software Development is a Job – Coding is a Passion

I'm Anders Abel, a systems architect and developer working for Kentor in Stockholm, Sweden.

profile for Anders Abel at Stack Overflow, Q&A for professional and enthusiast programmers

The complete code for all posts is available on GitHub.

Popular Posts

Archives

Series