Modified Description of Adding Inheritance into T4 Template from Chapter 18

Friday, August 20 2010

This is in reference to Programming Entity Framework 2nd Edition

When I originally wrote the directions for modifying the T4 template in Chapter 18 (Using POCOs and Self-Tracking Entities in WCF Services), I was working with the “almost” RTM version of the Microsoft’s POCO T4 template. Since my modified template continued to work after RTM, I never thought to revisit that text and discovered yesterday that it doesn’t follow the current version of the template and therefore the instrux are unclear & confusing.

My discovery did not come from a reader but was made when I was working with a client and wanted to make that same modification in her template.

When I originally wrote that description I was borrowing some code from the EntityObject template that had a dependency on a variable called ModelNamespace. But in the newer version of the POCO template, that variable is no longer used.

Here is the revised text from what is in the PDF version of the book pages 494-495:

You can download this modified template from the book’s website at www.learnentityframework.com/downloads

Modifying the template to apply the inheritance

Currently the entities generated from the model inherit from other entities only if that inheritance is defined in the model. For example, Customer inherits from Contact. Example 18-2 shows the template code, which uses an existing method in the template, StringBefore, to add inheritance to entities when they inherit from another entity in the model.

Example 18-2. The code that the POCO template uses to inject inheritance into an entity
<#=code.Escape(entity)#> <#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>

This ensures that the Customer class inherits from Contact, or that any derived entity inherits from its base, in the generated code.

But we now want to have every entity inherit from the new StateObject class unless the entities are already deriving from another base entity. In other words, Contact should inherit directly from StateObject, while Customer continues to inherit from Contact (and therefore indirectly inherits StateObject). To our good fortune, the EntityObject template uses similar logic to have entities inherit either from EntityObject or from a base entity. I used a method from there to devise similar logic for the POCO template.


First, you’ll need to add the method, BaseTypeName, shown in Example 18-3, into the custom methods section of the template where you inserted the MaxLengthValidation method in Chapter 11. This method came from the EntityObject template but has been modified to insert an inheritance to StateObject and to remove an unneeded call to another helper method.

Example 18-3. The BaseTypeName and MultiSchemaEscape methods to be used in the POCO template

string BaseTypeName(EntityType entity, CodeGenerationTools code)
{
  return entity.BaseType == null ? "POCO.State.StateObject" : code.Escape(entity.BaseType);
}

Now you can modify the code shown in Example 18-2, where the entity declaration is made to call the BaseTypeName method. As  result, the entity will inherit from either State Object or its base type as defined in the model.

<#=code.Escape(entity)#> : <#=BaseTypeName(entity, code)#>

Finally, if you placed the StateObject class in a separate project (as I did), you’ll need to be sure the entities can find the StateObject class. In the Entities project, add a reference to the new project.

When all of these modifications have been applied to the template, the generated entity classes that do not inherit from another entity should now inherit from the StateObject, as shown here with the Activity class:

public partial class Activity : POCO.State.StateObject