tangible T4 Editor Blog

News, Tip and Tricks from the tangible T4 Editor team.

  • Home
  • Blog
  • Blog Series: Model Driven Development with T4 templates – Part 2

Blog Series: Model Driven Development with T4 templates – Part 2

The second part of this blog series introduces the tangible Modeling Tools, a Visual Studio integrated designer for several UML-style diagram types, that can be used to create domain specific models. Later in this series we’re going to use a Persistence Model diagram (.tasl) to generate data classes and a basic UI from it using T4 templates.

 

image

 

Blog Series Overview

Part 1: Model Driven Development and Series Overview

Part 2: Create a Persistence Model using Tangible Modeling Tools

Part 3: Generating Domain Specific data objects using T4 and EntityFramework 5 CodeFirst

Part 4: Data Persistence and Versioning

Part 5: Generate a Basic UI using T4 and Windows Presentation Foundation

 

In this Part

Tangible Modeling Tools

Tangible Persistence Model Diagram

Create a Persistent Object Model

Continuation

 

Tangible Modeling Tools

Our Modeling Tools extend your copy of Visual Studio 2010 or Visual Studio 2012 by a set of UML-style diagram types and a designer for creating and editing those diagrams. The following diagram types ship with tangible Modeling Tools:

 

image

Activity Diagram

  Activity diagrams are used to visualize domain specific workflows containing actions, choices, parallelisms and iterations. In MDD they can be utilized to represent business processes between multiple components in a step-by-step manner.

 

image

Class Diagram

  Class diagrams display business objects in domain specific models. They visualize properties of these domain specific objects, what manipulations are available on them and any existing relationships between them.

 

image

Component Diagram

  In comparison to class diagrams, component diagrams provide a more macroscopic view on the specific domain. They define components that comprise larger building blocks of the domain, illustrating their interfaces that allow communication among components and represent dependencies.

 

image

Persistent Object Diagram

  Like a Class Diagram a Persistent Object Diagram models business objects in a specific domain. But additionally they visualize containment relationships between object classes, that indicate “responsibilities” – like creation or deletion of object instances.

 

image

State Diagram

  State Diagrams represent a virtual state machine describing the domain specific system and possible states this system can reside in. Specific external triggers can cause the system to transition from one state to another and communicate this to its environment.

 

image

Use Case Diagram

  UseCase Diagrams identify different kinds of users that can interact with a domain specific system and what operations they can invoke on the system. Additionally Operations (so called UseCases) can be structured into parts that may be reused or dependent on other operations.

 

All of those diagram types are intended to be used in a Model Driven Development process and model parts of the domain specific knowledge. Besides modeling the knowledge to communicate ideas between the stakeholders, the diagrams provide functionality for easily creating platform specific code using T4 templates.

For each diagram type there is a sample in our free T4 Template Gallery.

 

Tangible Persistence Model Diagram

In our blog series we’re going to use a tangible Persistence Model Diagram to visualize some domain specific knowledge and create data classes, a persistence layer and some basic user interface from it. So let’s have a closer look at the Persistence Model Diagram type:

 

First add a new .tasl file to your existing Visual Studio 2010 or Visual Studio 2012 project by right clicking the project and choosing “Add” > “New item” from the context menu. Select a “tangible Persistence Object Diagram” from the item category “tangible modeling tools” and name it e.g. “BlogSeries.tasl”.

 

image

 

Persistence Model Toolbox Items

Open the new .tasl-File in the designer and have a look at the Visual Studio Toolbox. The category “Persistent Object Model” provides you with items to build your domain model with.

 

image

 

  • Persistent Object
    A persistent object equals a class shape in a common class diagram. It represents a class of domain specific objects and contains properties and methods of those objects. A persistent object can have relations to other persistent objects or even inherit from an other persistent object.
  • Persistent Root Object
    The persistent root object is a special kind of a persistent object. It represents the logical root of a network of persistent objects connected by containments and associations. The existence of a persistent root object is mandatory for each Persistence Model Diagram. It cannot inherit from another persistent object and can only be the source of associations and containments.
  • Inheritance
    Two persistent objects can be connected via an inheritance item meaning that one of them is a specialization of the other. This relationship equals the specialization/generalization pattern of object oriented programming languages.
  • Property
    A persistent object can contain an infinite number of properties. The minimum information a property is its name and the data type that property stores.
  • Method
    As with properties, a persistent object can provide operations that may be executed on the persistent object. Methods must contain information about their name, the type of the return value and all parameters.
  • Association
    An association connects two persistent objects. Associations can be thought of as a property on each persistent object participating this association that contains one or more instances of the other persistent object – depending on the multiplicity set in the association’s properties.
  • Containment
    A containment is a special form of association between two persistent objects. The source of a containment (visualized by a blue diamond in the diagram) is considered “responsible” for the target object. It depends on the interpretation of the diagram what this “responsibility” means. Usually it means, the source creates instances of the target object and cares for their proper deletion.
  • Comment and Comment Link
    For explanation purposes, any item on the Persistent Object Diagram can be annotated by comments. Just drag a comment item onto the designer surface and fill it with commentary information. To assign a comment to a specific item, connect them with a Comment Link.

Features

Besides positioning and connecting toolbox items on a canvas the persistence object model of the tangible Modeling tools provides some additional features: those are model validation, auto-naming and extensible properties.

 

Validation
When you first open a new Persistence Model Diagram in the designer, Visual Studio will complain about not having a root object inside the diagram in the Error List. Visual Studio will also notify you if your persistent object model lacks proper connectivity between persistent objects: e.g. each persistent object needs to be reachable from the persistent root object via containment relationships.

 

Auto-Naming

When creating associations, tangible Modeling Tools will automatically create proper navigation property names. So creating a one-to-many relationship between the persistent objects “Person” and “Car” will result in a navigation property named “Cars” in the “Person” object and a navigation property “Person” in the “Car” object.

image

These properties will be kept in sync – so if you decide to rename the class “Car” into “AutoMobile”, the navigation property “Cars” will be renamed to “AutoMobiles”. There’s one exception to this rule: if you rename the navigation property manually to e.g. “Autos” it won’t be changed automatically, even if you rename the class again.

 

Extensible Properties

Extensible properties are the way to augment standard diagram models with custom information. If you are missing the possibility to store information to a persistent model, tangible Modeling Tools allow you to create this possibility yourself:

Open the “DefinedProperties” collection of a Toolbox Item in the Stereotype Editor and add the desired property to the item (we’ll use that feature later).

image

 

Create a Persistent Object Model

Now that we know everything about the features of the persistent object model, we need to create a domain specific (yet rather simple) sample model with which we’re going to start our Model Driven Development Process.

 

The Scenario

I came up with a very minimalistic model of a bank in which a bank serves customers by providing accounts and cash cards. A bank customer can obtain one or many cash cards, each one granting access to a single account.

Here is a screenshot of the final model built with the persistent object model designer:

 

image

 

Steps to create the model

Root Object “Bank”

Add a Persistent Root Object to the diagram by dragging it from the Toolbox onto the designer canvas. Name this object “Bank” either by double-clicking its header or changing the “Name”-Property in the Properties Window.

 

image

 

Add a Property to the Persistent Root Object. This can be done by dropping a Property Item from the Toolbox onto the Persistent Root Object or right-clicking the Root Object and choose “Add” > “Property”. Set the Name of the Property to “Id” and its Type to “Int32”. This property will serve us as unique identifier for a given bank in the persistence layer.

 

image

 

The same way add a “Name” property to the “Bank” object as a human readable identifier for a given bank.

 

Customer object

Then drag a Persistent Object item onto the designer canvas and name it “Customer”. The customer object gets three properties: an “Id” property of the Int32-Type (same purpose as the Bank-Id-Property), a property “FirstName” and a property “LastName”, both typed “string”.

 

Now connect the persistent root object with the “Customer” object using a Containment relationship, because if a bank is removed from the market, there’s no need to keep track of what people were customers of that bank. Select the “Containment” item in the Toolbox and then drag a dotted line from the Persistent Root Object to the “Customer” object.
image

A blue line will be drawn between the two objects with a small diamond shape at the side of the Persistent Root Object, indicating that the bank is the source of this containment, held “responsible” for the “Customer” object. Next to the line the navigation property names and multiplicities are displayed: "Bank” and “One” on the side of the Root Object and “Customers” and “ZeroMany” at the other end.

 

That information is read like this: “A bank has zero or many customers” and will result in a property “Customers” at the “Bank” object containing a collection of “Customer” objects. The other way round it means “A customer belongs to a single bank” resulting in a property named “Bank” in the “Customer” object referencing the only “Bank” object that customer belongs to.

 

CashCard object

Add another Persistent Object to the diagram and name it “CashCard”. Give it three Properties: “Id” (Int32), “Expiration” (DateTime) and PIN (string). Connect it to the “Customer” object via another containment dragged from “Customer” to “CashCard”.

 

This may be interpreted as follows: If a customer quits the service of a bank, all his CashCards become invalid. There is no need for a containment connection directly between “Bank” and “CashCard”, because the “CashCard” object is reachable from the Persistent Root Object via the path “Bank” > “Customer” > “CashCard”.
In our specific domain a bank would not create cash cards without the need to give it to a customer.

image

 

Account object

A bank holds an arbitrary amount of accounts. So add a third Persistent Object to our model and name it “Account”. An account contains an identifier (add an “Id” property of type “Int32”), an account number (type “string”) and information about its current rate (type “double”).

 

Since the bank manages all the accounts, the “Account” object is connected to the root object via a containment relationship.

But between the objects “Account” and “CashCard” we’re going to use an Association connection. On the one hand because the “CashCard” object is already reachable from the Persistent Root Object and on the other hand, because a customer can still carry his cash card around, even if the account has been deleted. So connect the two objects with an association with the “Account” object as the source.

image

 

Marking Identifiers

All objects in our model have an “Id” property. But this property is not different to any other property in the same object. That’s why we want to decorate this property with a flag that states “This one is the identifier property”.

Now we’re going to use the Extensible Property feature mentioned earlier:

 

Click somewhere inside an empty area in the model designer so that the the Properties-Window shows the properties of the “PersistentObjectModel” and click on the “…” button of the “DefinedStereoTypes” property:

 

image

 

This will open the “StereoType Collection Editor”. Select the member “Property” in the list on the left and click the “…” button of its “DefinedProperties” property to open the “ExtensibleProperty Collection Editor”. Add a new extensible property and set its default value to “False”, its name to “Identifier” and the Type to “System.Boolean”.

 

image

 

That way a new property will appear in the Properties Window each time you select a property inside a Persistent Object named “Identifier” and expecting a value either “True” or “False”. By default it will be set to “False”.

Close the windows again and select the “Id” property of the “Bank” object. Look at the Properties window and change the “Identifier” property to “True”. Do the same to all “Id” properties of the model.

 

image

 

Congratulations! You just created your first domain specific model to serve as a basis for generating data objects and a user interface in a Model Driven Development Process.

 

Continuation

Based on this Model we’re going to continue the following parts of our blog series on Model Driven Development.

In part 3 we’re going to create data objects based on this model using a T4 template to automatically generate C# code classes. Part 4 will create a data access layer for this model and the last part will generate a basic UI to create and manipulate data defined in this domain specific banking model.

Twitter Updates