Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

.NetTiers Architecture – Design Patterns Used

Stan Kennedy

The .NetTiers code generated framework provides a ton of functionality out of the box. I will not go into the Data Tiers such as the Entities, Data, and Data.SqlClient as deep because it’s a typical n-tier Data setup. What I’d like to focus on is the business/component layer.

First, before generating the component layer you can choose in the codesmith template a design pattern. The choices in the drop-down is: ‘Domain Model’, ‘Service Layer’, and ‘None’.
Obviously, if you choose to use .NetTiers for just the CRUD generation then select ‘None’. Selecting ‘None’ basically “draws the system boundary line” to the Data provider tier so the client or your custom business tier will call directly to this generated data tier.
The Domain Model pattern provides a web of interconnected objects. This pattern creates objects that represent both data and behavior. Most of us in the software world has built applications using this model. I will blog more on this option soon. Here is the UML…
The third option ‘Service Layer’ is what I will be focusing on in this blog post. In this type of command pattern, think of the Service Layer as the application’s system boundary. It provides the contract of how the client will interact with your system. Here is a diagram representing where the Service Layer is found:
When the Service Layer is generated, out of the box NetTiers will wrap your Data provider CRUD methods and add the following:

– Authorization – Uses Enterprise Library’s Authorization block. Basically you can set up AD groups and create a XML file that maps Users to the Entities and it’s methods. So for example, if you had a ‘Reader’ AD group and that group can only call the Get… methods.

– Exception Handling – Again, uses Enterprise Library’s Exception block and you can set up Exception polies quite easily.

Even if you do not put any business logic in the Service Layer, generating this tier will still provide the CRUD methods with the Authorization and Exception handling pre-wired. More specifically, the contract will be basically the same as the Data Provider methods with added functionality of Authorization and Exception Handling (which is worth it!).

If you would like to use this Service Layer for more robust business logic, it provides the framework based on some best practice patterns: Command Pattern, Processor Pattern, Routhing Slip Pattern, and Strategy Pattern. The Routing and Strategy is optional if you wanted to implement the processor pattern.

Command Patern: Serves as the workflow pipeline – a service instance provides the workspace for implementing your service type behavior. NetTiers provides the framework that allows you to add processors to the service and those processors are executed in the stated order. For example, let’s say you have a OrderService that would have a CreateOrder behavior. This behavior or use case would include many logical units of work including Validate Inventory, Check Inventory Location, and Place Order. You would load this pipeline up with each logical unit of work and call the OrderService.execute to process each behavior. Each process or behavior is represented by a class in NetTiers called a ‘Processor’. Here is the UML for the command pattern:


Processor Pattern: As I just mentioned, the Processor class represents each logical unit of work in any given Use Case (they could overlap, thus making them more flexible and resuable). For example, a processor called ‘ValidateInventoryProcessor’ may be used in the OrderService.CreateOrder and also OrderService.ManageNightlyOrders. You would create a new Processor class for each logical unit of work. This Processor class will inherit NetTier’s generated class ‘ProcessorBase’ which implements IProcessor interface. Basically, override the Process() method for your custom implementation in your new processor class.

So for new processor classes ValidateInventoryProcessor, LocateInventoryProcessor, and PlaceOrderProcessor you would do something like this to add them to the command/workflow pipeline for that service:
orderService.ProcessorList.Add(new ValidateInventoryProcessor(order));
orderService.ProcessorList.Add(new LocateInventoryProcessor(order));
orderService.ProcessorList.Add(new PlaceOrderProcessor(order));

As you can see, what would normally be coded in the Manager itself is now pulled out and can be used accross any service/use case. Pretty Flexible!!!

The ProcessorList provides the workflow pipeline for the order service. When execute is called it will iterate and call the Process() method for each of the processors loaded in that sequence. Additionally, NetTiers will track the results and state of each processor and store the results in a ServiceResult class. This class will track broken rules and exception errors as it’s iterating each processor. This generated class implements the IProcessorResult and returns a GenericProcessorResult. So the execution of the service works as simple as this:
ServiceResult = orderService.Execute();

If you want to know if any problems occurred, you would simple call the HasErrors:
if( ServiceResult.HasErrors) …{handle them here…}

Here is the diagram of the Processor Manager Pattern: As mentioned earlier, this ProcessManager manages sequence and state of each processor (logical unit of work).

Here is a screen shot of the Generated Service project from NetTiers. Notice the Processor folder and the base/interface classes generated for you. You would simple add your Processors in this directory:

Routing Slip Pattern: This is an extension of the Processor pattern when sequence is not known at design time. Implementing this pattern is optional and can add more flexibility to your application. The idea here is that instead of coding the Manager to load each Processor in a certain sequence you implement the routing slip to instruct the manager what to process next. To implement this, attach a Slip to the message specifying sequence of processing steps (as opposed to the process manager coded for this). Next attach special message router class that reads the Routing Slip. Here is a diagram of the Routing Slip Pattern:

Strategy Pattern: Finally, for even more flexibility you can utilize the Strategy pattern. This pattern utilizes small classes that contain different algorithms. So instead of putting the caculateInventory logic in the Process() method of the ValidateInventoryProcessor class, you can create a strategy class called ‘EasternRegionInventoryStrategy’, ‘CentralRegionInventoryStrategy’, and ‘WesternRegionInventoryStrategy’. Each one of these concrete classes inherits from a base strategy class ‘RegionalInventoryStrategyBase’. Now, any processor class can call the algorithm based on the context.
Class Diagram for Strategy:

Example of Strategy class: ‘EasternRegionInventoryStrategy’
Context Class: ValidateInventoryProcessor
Abstract Strategy Class: ‘RegionalInventoryStrategyBase’
Concrete Classes: ‘EasternRegionInventoryStrategy’, ‘CentralRegionInventoryStrategy’, and ‘WesternRegionInventoryStrategy’

Obviously, this adds quite a bit more complexity and can always be implemented later by pulling out the algorithm in the Process() methods. If you are new to patterns or NetTiers you may want to do this later.

Implementing best practice patterns has long been accepted as a way of architecting software. The key is to go ahead and do your homework, understand the patterns, and then implement them. The great thing about NetTiers is that the framework is generated quickly and ready to use.
References used:
http://nettiers.com/ComponentLayer.ashx
http://www.dofactory.com/

2 Comments. Leave new

[…] this link: .NetTiers Architecture – Design Patterns Used application, Design, load-each, manager, not-known, pattern, processor, property, routing, […]

cesar qüeb
March 6, 2012 5:46 pm

Thank you for the info.. More clear that available in official site.!..
Cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

\\\