Defining the service layer dependency tree using UML Sequence diagrams and the Dependency Injection pattern
UML sequence diagrams can be used to identify interfaces for an application's
Service layers which in turn can be used to generate a service layer dependency tree.
When designing an OO application there are three different object types to consider, in accordance with UML standards and robustness analysis. They are the entity, boundary and controller objects which map to the MVC paradigm respectively.
The Model within the MVC pattern contains the core business logic of the application, and two types of objects exist within it:
Entity (database) objects
These objects are easily identified in our use cases from the nouns.
Entity objects map to the tables in the database and define the data entities that the application will manipulate. These objects are persisted to the database when changes occur. These objects normally include implement their persistence functionality through interfaces as depicted in the "domain object persistence pattern". These objects are also generally easily defined and identified by understanding what data needs to be persisted by the application. A tree like object structure can normally be generated along with the related persistence code using code generators.
The business objects along with the entity objects belong to the Model in the MVC pattern. The Business objects define a particular set of services required by the application.
Defining the interfaces for the different service layer objects and understanding their dependency on one another is integral to leveraging the re-usability and “plug and play” type architecture that OO systems allow for.
The business objects are the primary objects that manipulate the application’s entity objects, communicate with the controller objects and define the "service layers" of an application, otherwise known as an application's business service layers.
The key lies in the application of UML sequence diagrams. Once the use cases have been developed the use cases can be used to assist in identifying what general services which are required in the system by looking at the actions that take place during a particular use case.
As an example I will use a simplified notification system to explain what I mean.
Use case:
1. User subscribes with the system.
2. The user provides search criteria information that defines the user’s profile.
3. The system checks the newly added system data on a daily basis against the user’s profile to determine whether the user should receive notifications.
3. Notifications are not sent if a user’s subscription is no longer valid.
Data entities defined from nouns:
User
Notification
Subscription
Profile
You will notice that although the data entities have been identified, they say nothing about the actions (business logic) required to fulfil the system’s purpose.
Processes that can be identified from the Actions/Verbs within the use case can be used to derive the business services required by the application.
Service entities (business objects) that can be identified from the use case:
|
Service |
Responsibility |
|
Subscription service |
Managing user subscriptions. Checking whether subscriptions are still valid. |
|
Data service |
Updating and inserting data into the database. |
|
Search service |
Building the search criteria from the user profile to search the database and retrieve notifications that must be sent out. |
|
Notification service |
Send out the notifications to users who have a search profile with criteria matching the recently added data. |
We could derive a scheduler service also from the above use case but for the purpose of this article and to keep things simple, the notification service will assume this responsibility. In certain instances it’s beneficial to break up service components as soon as they start taking on responsibilities that don’t neatly fit into their category of service.
“Subscribing” implies that there is some kind of "data service layer" that the system required to load and store data in the relevant data store.
You will notice that nowhere in this article do I refer to a particular type of technology in terms of data store or data packets (eg.ado.net datasets, xml) retrieved from the data store. The use cases and sequence diagrams ONLY depict objects within the UML modelling language. The technology used to develop the system or the data store used to store the data is up to the developer.

Derived Interfaces from sequence diagram

Identifying the Service Layer Dependency Tree
You will notice that subscription service layer relies on the data service layer to insert profiles and subscriptions. The subscription service also relies on the search and notification service. The search service relies on the data service to return notification data.
The resulting class diagram will thus look as follows:

Windows forms VS. ASP.NET applications
A common design error made by developer's that have done a lot of windows programming is the abuse of the object entity tree within web applications. Loading the entire object tree into memory gives a developer an enormous advantage when developing windows applications in that they have instant access to any data entity in the database and their persistence functionality.
What you have to bear in mind is the short lived life cycle of the entity object within web applications versus the long lived life cycle within windows applications. This means that within web applications it should only be useful to load the necessary data entity objects into memory that you are interested in displaying within the requested web page.
I generally find that using inheritance tree structures within an application ties one down to a particularly rigid set of inheritance rules within your objects and doesn’t allow for the type of polymorphic flexibility that interfaces provide.
Interfaces also promote a plug and play type architecture within the different service layers of the application (i.e. layers of the application can be removed and substituted with other objects as long as they implement the substituted layer's interface(e.g. the data service layer)).
Dependency injection also forces the layers to be created in the correct order and allows these layers to be easily identified within the sequence diagram as depicted earlier.