Click here to Skip to main content
13,352,175 members (75,958 online)
Click here to Skip to main content
Add your own
alternative version


23 bookmarked
Posted 24 Sep 2008

Web-Application Framework - Catharsis - Part VII - Entity layer

, 3 Oct 2008
Rate this:
Please Sign up or sign in to vote.
Catharsis web-app framework - Entity layer


This article is the next step in Catharsis documented tutorial.  Catharsis is a web-application framework gathering best-practices, using ASP.NET MVC (preview 5), NHibernate 2.0. All needed source code you can find here.


New solution VI CatharsisArchitectureXI (Controller layer - undone)  
II Home page observationVII Entity layer XII (UI Web layer - undone) 
III Roles and usersVIII Data layer XIII Tracking, PAX design pattern
IV Localization, translationsIX Business layerXIV Catharsis Dependency Injection (DI, IoC) 
Enter into Catharsis, new Entity(Model layer - undone)  XV (Code Lists - undone)    

Entity layer  

At this chapter you can find summary of the Entity layer. From my experience, what I always wanted and expected from tutorial - give users (colleagues) the quick description of what could not be seen - easily seen from the first observation. If there is something what make a sense as a whole, explain it; what could be easily read from code do not describe, and force developers to examine...

Guidance, Guidance, Guidance ...

The first step to efficiently work with Catharsis is to use her Guidance. If you’re not experienced with MS Guidance, than do take your time, and examine it. At least install Catharsis.Guidance and try to create your own solution. Next step must be observation of class generator abilities. Right-Click on any Project library and in the context menu you'll see the picture of a cat and quick description of available action. 

Try it; try it; try it. Your tests and (hopefully) next few chapters will help you to get quickly in.

Catharsis.Guidance can help you create whole infrastructure for handling any entity (Entity means Person, Contract, Client, Car, Table, Goods item...). If you'd like to work in steps, you can use class generators on every layer as well. Let’s have a closer look at these Guidance wizards.  

(Re)Create all entity’s infrastructure menu item can be found on projects Entity.dll and Web.dll. 

(Re)Create objects on the current layer could be accessible from any project (right-click).

At this chapter we'll discuss Entity tier, which is about plain objects. Guidance generator for this project will produce 2 files with two classes. The first is ‘Entity.cs’ file containing persistent entity with its properties. The second is searching object, which could be used and filled on UI, and next on data layer used to filter list of searched entities. 

Base classes for persistent objects

Objects in Entity.dll are (even have to be) plain, method-less. Their ancestors provide some basic needed functionality for handling. It is built-in and you don't have to care when creating new entity. You can concern only on the business case. There are two main base objects. They have some similar behavior:

Persistent base class   

The simpler one is Persistent which is derived from. Catharsis.Entity.PersistentObjects.SimplePersistentObject. It comes from Billy McCafferty SharpArchitecture 0.7.3 (Catharsis uses many great already created things and is also proud to inform about it) Every such an object provides this property and methods:

public virtual int ID { get; protected set; }
public abstract string ToDisplay();
public virtual bool IsTransient();
public override bool Equals(object obj);
public override int GetHashCode();
// protected
protected abstract string GetDomainObjectSignature();

Property ID will be the database unique key. Catharsis uses that value as the main and only indicator on UI (when navigating from the list into the detail, object ID is used etc.). All entities has ID and its type is always int, by default. That behavior can be changed if needed. You can also change auto-incrementing generator to some Guid based one, to make more difficult for attackers gues which number will come next. It is upon you.  

The ‘indicator-method‘ IsTransient() can help you to decide between already persisted and newly created objects (If ID is not set yet object is transient).

There are some methods needed to distinguishing among entities (of the same type) GetDomainObjectSignature(), GetHashCode(), Equals(). The first one must be implemented in every derived class (its abstract) and all together then can help you decide if instances are equal, nevertheless one of them is transient (without DB yet provided ID). 

When implementing abstract GetDomainObjectSignature() you should return string based on properties(y) which together represent unique business key. In typical case it will be the ‘Code’ property. 

Persistent does not implement the IComparable interface (at current version). If you need such, or any other functionality, which all of your object should share, Persistent class is the right place to implement it. Encapsulation is the pillar of OOP, but the usage is not so often as it should be ...

In cases you need to display entity and you don't want solve which property to use, Catharsis enforce you to provide ToDisplay() method. On UI layer it then could be simply used in combo-boxes, lists etc. And what’s more the object.ToString() method can still serve you for other purposes.  

Tracked base class  

The second base class (and more powerful one) is Tracked derived from Catharsis.Entity.PersistentObjects.TrackedPersistentObject. Its main purpose is to extend Persistent and provide tracking functionality. The list of implemented methods:

LifeCondition Condition { get; }
bool MakeAlive();
bool MakeExpired();
bool IsReadOnlyMode { get; }
bool IsTrackedMode { get; }
IList<IChangeSet> Changes { get; set; }
IChangeSet NewChange();
IChangeSet AddChange(IChangeSet changeSet);
DateTime ValidFrom { get; set; }
DateTime ValidTo { get; set; }
DateTime? ToDate { get; set; }

As you can see, all of these built-in features are concerned on changes tracking. They follow Tracking PAX design pattern (to see the power of Catharsis for storing changes see Chapter XIII - Tracking, PAX design pattern). If you’ll decide to derive from this base, you’ll get tracking functionality without any other needed coding. Any change on ‘Alive’ object is stored. Therefore can be simply restored by changing Historical DateTime property. That's another Catharsis framework feature.

TrackedPair base  

We should also mention TrackedPair base class, which will help you to handle collections on Tracked objects. For example, there are AppRole and AppUser objects built-in Catharsis. Any AppRole instance can contain any AppUser instance in its inner collection (AppUser.AppRoles and the opposite AppRole.AppUsers). Items in these collections are time-dependent. It means that User ‘Radim’ can be in role ‘Admin’ from beginning of the year 2007 till the end of 2008. End even then from June 2010 till he will leave … (DateTime positive infinity). The time stamp for being in role could be crucial (for example security issues, auditing, proving …). 

There is lot of functionality built-in Catharsis to allow you handle pair collections as simple as it could be. The best way to understand is to examine AppRole and AppUser implementation.


Your own new entity class is derived from one of above uncovered bases. It should contain any property and should NOT contain any method. The example comes from (and will follow) previous chapters: 

public class Person : Persistent
    public virtual string Code { get; set; }
    public virtual string SecondName { get; set; }
    public virtual string FirstName { get; set; }

    public override string ToDisplay()
        return SecondName + " " + FirstName;
    protected override string GetDomainObjectSignature()
        return Code;

The amount of properties is not limited, for tutorial purposes are three enough. The first (up to 3) string type can be created for you when using Guidance.


The more you are experienced with NHiberante, the more you are familiar with unlimited potentialities for searching. You can create as many nested Criteria as you (your customers) need to satisfy your (their) needs. If Contract has Supplier, which has Subject, which has Address, which has City … you can easily ask for ‘Contracts’ from ‘Prague’ coming supplier’s.     

To use these features you have to collect filtering criteria from application user. Catharsis provides separate UI handler for every Entity - searching screen. Whatever you want to allow user to use as filter, you should provide on that screen. Filled ‘form’ is then very simply (please examine provided source code) bind to Search object, which can be send to Dao and converted to filtering criteria.   

Searching object is good example to prove that Catharsis is a solid OOP framework …

Guidance usage  


We’ve started with guidance and described what Entity-tier is about. Let’s resume the generator usage. Create new folder in Entity project called People (if not exists), and right click on it.

As shown on the picture, select the item (Re)Create ‘Entity’ class. On the next two pages of the wizard you have to fill in the entity name: Person. That name will be used for the file name as well. And you can get up to 3 properties of string type. 


The last input expects the namespace – by default it is the folders name (People). If you are on the project level, the Root namespace suggestion will appear. If you do not change it, then Guidance will create items on the root level of the project - not in the Root directory nor in the Root namespace (It comes from Guidance demand for unempty value for the namespace)
Next page allows you to check if Entity will be Tracked (see Chapter 13 Tracking, PAX design pattern) or not. You can also decide if Entity should be handled as CodeList value. For example Country, Currency (built-in Catharsis) or your own values could be handled as the CodeList values.

The difference in their behavior comes from two assumptions. The set of possible values is limited and not so large to be displayed in combo-box or even radio-button set. And that values are not changing in time (at least not so often). Other good example could be your own CodeList for evaluating: bad, neutral, good. 

The advantage of CodeList objects comes from built-in localization for these objects. CodeLists can be adjusted or even translated and therefore displayed to user in friendly form, despite of the fact that are handled and stored by ‘ID’ or ‘Code’ without obvious meaning (1 – bad, 2 – neutral, 3-good).


Click ‘Finish’. Two new files will be added to the Entity project (or they will replace old ones – be careful, all your previous changes will be overwritten).

Generated skeleton


Both generated files (classes) are only the starting point which could help you concern on the business case. Now come into play your customer needs and requirements. 

You have to implement as many properties (not only string type) as newly created object needs to satisfy customer’s needs. And also as the collection of application entities will growth the same could be applied to the searching object. New properties will extend the filtering power of your searching screen.     

For example amount values could be filtered by properties ‘EqualOrLess’ and ‘Greater’, the same goes for DateTime values,  etc…

How to persist Entity uncovers Chapter VIII - Data layer.

Enjoy Catharsis.

Source code


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Radim Köhler
Web Developer
Czech Republic Czech Republic
Web developer since 2002, .NET since 2005

Competition is as important as Cooperation.


You may also be interested in...

Comments and Discussions

QuestionDoes Entity Layer support composite database table key? Pin
wadep8-Oct-08 7:00
memberwadep8-Oct-08 7:00 
AnswerRe: Does Entity Layer support composite database table key? Pin
Radim Köhler8-Oct-08 7:24
memberRadim Köhler8-Oct-08 7:24 
GeneralRe: Does Entity Layer support composite database table key? Pin
wadep8-Oct-08 12:57
memberwadep8-Oct-08 12:57 
GeneralGood information - Does Entity Layer support composite database table key? Pin
Radim Köhler8-Oct-08 20:49
memberRadim Köhler8-Oct-08 20:49 
GeneralGood work. Pin
Rajesh Pillai24-Sep-08 19:56
memberRajesh Pillai24-Sep-08 19:56 
GeneralRe: Good work. Pin
Sacha Barber26-Sep-08 6:38
mvpSacha Barber26-Sep-08 6:38 
GeneralRe: Good work. Pin
Radim Köhler26-Sep-08 7:41
memberRadim Köhler26-Sep-08 7:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.180111.1 | Last Updated 4 Oct 2008
Article Copyright 2008 by Radim Köhler
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid