Firm.Insurance III
Example project; CodeLists and the Guidance Recipes
Story list: part I, part II, part III, part IV, part V, part VI, part VII, part VIII
index
- Analysis, Entity Model - part II, overview
- Guidance Recipe - first contact
- Guidance Recipe - COMPLETE WEB infrastructure
- Recipe finished, infrastructure created
- Run application, Currency CRUD operations are working
Analysis, Entity Model - part II, overview
In the previous story (part II.) we've started with the Business Analysis. We've uncovered the Application Entities and decided how to store them in DB.
http://catarsa.com/Articles/Code/Example-Insurance-Company-02-Entity-Model - part II
The starting point - how to create new solution - is described in the part I http://catarsa.com/Articles/Code/Example-Insurance-Company-01-New-Solution. Described topic resulted in the .zip file with the newly created (empty) project. That's the point we will start now.This story presumption is newly created project (part I) and the agreed Entity model (part II). In next paragraphs we'll be concentrating on the CodeLists. There were identified: Currency, Country, Product, AgentType, PaymentPeriod. The first of them Currency will be implemented in this story
Download the result of this story: working solution extended with just created Currency management..
Guidance Recipe first contact
The Catharsis framework Architecture has three tiers (Data access, Business rules, MVC) and many .NET projects to enhance separation of concern. Whenever we are adding new Entity to the application we have to extend every layer, and almost every project. This is very very slow, ugly and dangerous - leading to dozens of mistyped errors.
The Catharsis Guidance will help us in this way. There are many Guidance Recipes, which firstly pop-up the wizard to gather all needed information, then extend every project with new(updated) .cs, .aspx, etc. files, filled with the basic classes skeletons.
The Recipes are available (for example) by right click on the Project, Project.Folder. When you right-click, the context menu appears, the Guidance Recipes (decorated with the cat head icon) are available.
Every project in the solution has different set of the Recipes. Usually there is a recipe which targets only the selected project. In some cases, there are Recipes targeting the cluster of projects e.g. the Entity, Buisness, Common, Dao and Tests for entities without separate UI (useful for FileSystem access, Email trigges...)

The above picture shows our application as just created, empty solution. We've expanded the Entity project, and right-clicked on the Folder CodeLists. The three Recipes are available:
- (Re)Create 'Entity' class
- (Re)Create COMPLETE WEB infrastructure
- (Re)Create Project - (Entity, Business, Common, Test)
1. (Re)Create 'Entity' class
The simplest one, targeting only the Entity project. This Recipe will create files for entity (e.g. Currency.cs in the folder CodeLists) and its search object (e.g. CurrencySearch.cs in the folder CodeList\Search)
Despite of the fact, that generated files are placed in different folders, both have the same namesapces: Firm.Insurance.Entity.CodeLists. The reason is to reduce the using clauses, while keeping the structured files in folders. The larger project is the more using statements we need for simple dummy call...
2.(Re)Create COMPLETE WEB infrastructure
The most powerful and the most used Recipe. This one will target each and every solution project handling entities. There will be more then 20 files created. We will see soon...
This recipe is also available on the Web project.
3.(Re)Create Project - (Entity, Business, Common, Test)
This Recipe is available also on the Business project, and targets all projects in the Project and Project.Test Solution folders. Other words, this is similar to previous, but without the UI projects. As already said, it is useful in many scenarios, when you need to access Entity from persistence via Facade (and test in Test project), but there is no need for user interface. The good example could be FileSystem operations for enclosed files, Statistics entity (triggered in AOP filter) storing some user data...
In general, usual approach is the 'COMPLETE' infrastructure; sometimes everything till the Business layer is enough. The project base recipes are good for 'RE'creating.
Guidance Recipe - COMPLETE WEB infrastructure
We need to create the Currency (CodeList) Entity infrastructure. Infrastructure in this case means:
The set of objects needed for Entity handling - from persistence, through the Business Rules validation, to the User and back.
OK, Select the (Re)Create COMPLETE WEB infrastructure Recipe. If you were on the CodeLists folder you should see the screen like this:

The Class Name textbox will have impact not only on the Entity name, but also on the generated file names. Currency.cs, CurrencySearch.cs, CurrencyDao.cs, CurrencyFacade.cs ... and that's one of many reasons why this name should be selected very wisely. You can use this recipe to regenerate these files later again, but there is no built-in way, how to remove all the files at once.
The Class Name value should be unique through the application. There will be namespace applied - that's true and good. But: for some purposes (ASP.NET MVC) the entity is distinguished only by its name! The CodeLists.Currency and the MyNamespace.Currency won't work properly because the controller for URL routing would be simply the Currency.
NOTE: keep your Entities with unique names
Next TextBoxes represent the Entity's properties. You can fill in up to three of them. All will be inserted in the generated classes as the string properties. These are intended as helpers, which will give you some 'guiding example' for other properties. We will use it in next stories, for 'full' properties. For the 'CodeLists' entities, leave it as it is.
The last TextBox contains the namespace for your Entity. The filled value comes from the folder name on which we've right-clicked. Currency Entity will be nested in the Firm.Insurance.CodeLists] namespace. You can change this value as needed. If the namespace value will be new (no folder of the same name is currently existing) the Guidance will also create these folders in all affected projects.
NOTE: The CodeLists namespace will be CodeLists anyway... it will force the using statements reduction.

The next page of the wizard provides three switches (as shown above).
- base class
- ID type
- DaoBase - persistence type (only for the Data access layer)
1. select a base class
Entity's base class could be the 'full' Persistent or the CodeList. All (full) Entities are derived from
Persistent object, the simplified entities (described in this story) are inherited from CodeList object.
CodeList ver. ICodeList
CodeLists are in general all the same and for such types, there is a ICodeList - simple choice (the last one in the wizard). The 'same' means, that they do not extend the CodeListBase properties. If there is need to extend the new CodeList entity, for instance the ContentType with property Suffix, use the second choice CodeList - separate entity
The main difference is in the base implementation sufficiency. The ICodeList (Currency, Country) which need only the existing properties, can reuse even the UI elements. The generated files count is smaller. The CodeList like ContentType with new properties will need separate UI for the new properties management - generated are also the UI pages and controls.
2. select ID type
If you are creating new application with ability to design the DB tables, you should select int as the ID type. For almost every scenario it is wide enough range and the space in DB takes 4 bytes. Even for Entities, which do have the smallint or tinyint types of the ID in database, use the int on the C#, .NET side. It will allow you (in the future) change only the database type - the .NET application won't be damaged anyhow.
In cases, that your application is handling data from existing DB storage (or any other storage like WebService) and you have to map the ID as the long or Guid - do it. The Catharsis framework Guidance is now supporting the entities with 'struct' type IDs.
The ID type is essential as the unique identifier. It's used on every layer, even on the UI for the URL Routing. The ability of Catharsis to support long and Guid IDs will save you many sleepless nights when accessing original databases. You will declare the ID type only once (while creating the infrastructure with the Guidance support). Form that moment any issue about the ID like Guid is solved and working.3. DaoBase - persistence type (only for the Data access layer)
NHiberante, ADO.NET, XML - three (currently) supported DAO base types. If you can access DB directly (without Stored Procedures) the best (and almost the only) choice is NHibernate.
In the future maybe the MS Linq to Entities 4.0 could compete with this approach...Catharsis will create for you EntityDao object derived from the NHibernate Dao base, which out of the box implements all the write operations. Your only concern will be the GetBySearch() operation: map the filter parameters into the Criteria statements.
If you are accessing DB but the only access is via Stored Procedures (100% created by the third party), you have the only choice: ADO.NET. In this case, you will end up with the EntityDao class which need to be implemented completely. You have to map Stored Procedures to every CRUD operation manually.
The worst scenario, damn DB designers with damn tool like 'Stored Procedure'.Finally, you can bet on the AppData folder for some Entities, as the .xml files persistence. In our example we are using this approach for Services objects (Transaltor, Articles), so you can quickly observe them, and get the feeling how the XmlDao works. Catharsis is doing a lot in these cases, the base implementation provides all CRUD operations, you have to extend the GetBySearch() as with NHibernate, and maybe adjust the XML-Entity mapping.
Wizard: FINISH
Well, its time to click the 'Finish' button and let the Guidance 'Recipe' create the infrastructure.
Recipe finished, infrastructure created
The Recipe wizard was filled, 'Finish' button was clicked. After few seconds you should be provided with the message box as shown on the picture.

In the CodeLists folder we can see the newly created file Currency.cs with the new CodeList Entity Currency. Message box informs us, that everything was correctly created and we do have to:
- Create new Controller name constant
- Extend the Menu.config file with the access rights
Controller constant
The Catharsis framework use for some data handling also the strings. Not as perfect as could be, but currently needed for instance for URL Routing (controller and action names as strings). Every entity has its core constant stored in the Str.Constants class. This value is used on many places, so to decrease the potential risk of mistyping the "Currency" string (e.g. "currnecy") we will use the constant.
The core constants for all Entities are placed in the subclasses Str.Controllers. As shown below, we have to extend this definition with the
public const string Currency = "Currency";
Navigate to the Project Solutin folder -> Firm.Insurance.Common project - > Constants folder and select -> Str.Controllers.cs file. Extend it with the above declaration as shown below.

Menu.config - grant access
The second setting is the permission. We are currently working with the application as the 'Administrators' - the Current Role principle. So we have to do append access rights to the Currency Entity management for (at least) Administrator. These settings are placed in one separated (and easy to maintain) file: Menu.config.
Navigate to the Project.Web Solutin folder -> Firm.Insurance.Web project - > Config folder and select -> Menu.config file. To grant rights for Administrator we can append these snippet into any other ControllerOrNode element. The parent element will then act as the TreeView Node Parent:
<controllerOrNode name="CodeLists" ... >
<!-- Currency -->
<controllerOrNode name="Currency" >
<roleGranted name="Administrator" />
</controllerOrNode>
...
</controllerOrNode>
this will grant access right only to the 'Administrator' role. If we want to append other roles, we can do it by adding the roleGranted element with others role names and even with some restrictions
<!-- Currency -->
<controllerOrNode name="Currency" >
<roleGranted name="Administrator" />
<roleGranted name="RegisteredUser" />
<roleGranted name="Viewer" isReadOnly="true" />
</controllerOrNode>
That's fine, but the more roles and controllers you have, the more xml code needed. To reduce this we can use predefined role groups, which are also hosted in the Menu.config file, for instance one built-in group is "All"
<roleGroup name="All">
<roleGranted name="Administrator" />
<roleGranted name="RegisteredUser" />
<roleGranted name="Viewer" isReadOnly="true" />
</roleGroup>
This will allow to simplify the Controller access rights settings this way:
<!-- Currency -->
<controllerOrNode name="Currency" >
<roleGroup name="All" />
</controllerOrNode>
Great, and finally the picture with the resulted Menu.config change

Finished. Build and Run it...
Run application, Currency CRUD operations are working
Build and run the Application. Hurry, press the F5!

Expand Code lists node in the left TreeView -> Select the Currency node. You can even try to create few new entities (EUR, USD). You can also search (filter) them, page and sort them... that all in detail we will observe in next stories.
Download the result of this story:
The above zipped file contains the working solution, which is the same as up to now described stuff in this example stories. To run it DO NOT FORGET:
!!! Change AppData\User.Xml Login property to your localhost account
Next?
Well, right now and you can also append the 'DUMMY' value, or any other incorrect value. That's because there are missing the Business rules. In a next story we will declare them on the CurrencyValidator and test them with Unit tests.

