POCO and T4

Tue 15 May 2018

It’s been a while not writing any post, I’ll try finish this series before I get tired of it. This time I’ll talk about two words - POCO and T4

What is POCO?

POCO is Plain Old CLR Object; a word from POJO - Plain Old Java Object - maybe, if for Lua it would be POLO, Golang is POGO, php is POPO, etc.

CLR is short for Common Language Runtime. It’s a very correct definition for POCO but to be easier, just use C# instead.

Plain Old - means simple, straight, no dependency whatsoever.

POCO class looks like this:

public class Product
{
    public string Code {get; set;}
}

And Non-POCO class:

[EdmEntityTypeAttribute(Namespace="CMSModel", Name="Product")]
public class Product: EntityObject
{
    [EdmScalarPropertyAttribute(EntityKeyProperty=true)]
    public string Code {get; set;}
}

Why POCO is better than non-POCO?

Think of you already created a non-POCO classes that inherited or attributed with heaps of classes from EF libraries. You put all of these classes into assembly A, and you have another business project B which is dependent on A. Because you need to write logics for these classes so you also referred EF libraries in project B.

Normally you don’t update EF references in A too often as it may introduce unnecessary issues. As projects increasing, the dependencies become very complicated. EF library upgrade involves more and more projects that dependent on A or B.

At this point, if you have a project C and somehow it depends on A or B (closely or far away). Somehow, project C happen needs another functionality in one of EF libraries; a higher version than the one referenced by project A. Then the conflicts come up.

Some time you can be aware of the conflicts and avoid them in advance. But some time you wouldn’t notice them until something is wrong.

But if you use POCO at the very beginning, you won’t have these trouble as you never reference EF libraries in A or B.

What does POCO to do with Entity Framework?

CSDL defines the conceptual models, but it’s not possible to code with the XML data.

csdl

To archive this, Visual Studio analyzes the CSDL data and automatically generate C# classes. (Microsoft used to love making things automatically. End-users love that but not the programmers, especially when they frequently get a blue image on their screen.)

The generated classes are non-POCO classes and it would introduce issues that we mentioned earlier.

With POCO classes, the models are more deliberate now. Any changes on framework or dependencies won’t effects the existing codes.

The whole process used to be CSDL -> Auto Generating -> Generated Classes . EF takes CSDL as input and domain classes as output.

Now the process is CSDL -> POCO Classes -> Auto Mapping. Both CSDL and POCO classes become input and EF will get them mapped at runtime.

The removed Auto Generating later became the new Code Generation tool — T4 Template.

What is T4 Template?

T4 is short for Text Template Transformation Toolkit. It’s a template processor, similar to Razor in ASP.NET. Normal template processor render for html, and T4 also supports rendering code from code.

It’s like writing code to let it auto write code. Unfortunately, it is not as fancy as it sounds like. Sometimes it introduces more troubles than what it might have saved.

There are two signs to tell if use T4 or not. First, do you need to write similar code for a large amount of sources? Second, will you modify the generated code frequently(can it be overwritten safely)? Both of them are what POCO meets.

Here’s an example of T4 template:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
namespace T4Testing
{
<#
var ttFilePath = this.Host.ResolvePath("");
var data = File.ReadLines(ttFilePath + @"\data.txt");
foreach (var line in data)
{
#>
    public partial class <#= line#> 
    {
    // Something
    }
<#
}#>
}

It reads lines from data.txt file and generate partial classes for each line.

data.txt:

    Pyramid
    Cube

code.cs:

namespace T4Testing
{
    public partial class Pyramid 
    {
    // Something
    }   
    public partial class Cube 
    {
    // Something
    }   
}

Frankly speaking (typing), writing a T4 template to generate code is more interesting than what it is generating. For modern IDEs like Visual Studio, with or without ReSharper, it always provides a deadly easy way to guess what you are trying to code. T4 is useful only if you need to type a large number of similar code. Even in that case, it is more likely a one-off thing that you can throw it away as soon as it has created the classes. Because the more important and difficult part for each class is business logic.

Some would say that logic can also be defined in structured format like XML. It’s doable but if so you’ll need to write code to parse and convert them from XML to your T4 code. The effort and complexity is not reduced by doing so and it will even create a lot of new troubles.

Category: EntityFramework

Tagged: ef

Comments