Layered Architecture: Partitioning the Code

Developing an enterprise layered application can be a daunting task especially when the layered samples provided, contains a barrage of Visual Studio projects. So, here's a brief description of what each folder and projects are for in the samples found in Layered Architecture Sample for .NET and also those that were unfolded by the Layered Architecture Solution Guidance (LASG) Visual Studio extension.

Business
This folder should contain all projects and assets that are related to the business layer. If you have any classes that are only shared between business layer components, you can create a [Project-name].Business.Framework project to hold them in here.
  • [Project-name].Business This project should contain all the main business components. The classes here should contain all the business processing and validation logic.
  • [Project-name].Workflows This project should contain all the WF workflow components that orchestrates the business flows. The classes here are stored as .xaml and will be compiled into a dll later. This is not a .xamlx project.
  • [Project-name].Workflows.Activities This project should contain all the workflow activity and related classes. Workflow activities facilitate the easy construction of workflows. Composite activities should reside in this project as well even if they are with the .xaml extension.
  • [Project-name].Workflows.Designers This project should contain all the workflow and activity designer classes. The classes here are to facilitate the designer experience of Visual Studio and should not be deployed to the application server. 

Data
This folder should be used to group all the projects and assets that are related to the data layer. Any classes that calls external web services or accesses other data storage such as the file system, SharePoint lists or message queues, the should also be located here. If you have any classes that are only shared between data layer components, you can create a [Project-name].Data.Framework project to hold them in here.
  • [Project-name].Data This project should contain all the components that interacts with the database. Place all CRUD code in this project.
  • [Project-name].Data.AgentsThis project should contain all the components that interacts with other storage systems such as file, SharePoint lists or Queues. This project does not unfold by default in LASG.
  • [Project-name].Database This is a SQL Server Data Tools (SSDT) project that is used to hold database scripts and publish them to the database server. You can also use this to keep track of design and schema changes by checking it into a version control system such as Team Foundation Server (TFS). This project does not unfold by default in LASG.

Hosts 
This folder should contain all the host projects that will be deployed onto the application server. You can create as many host projects as needed depending on your hosting needs.
  • [Project-name].Hosts.Web This project should contain all the assets and configuration for hosting the services back-end in the application server. This is the entry point to the application server.

Presentation 
This folder should contain all the projects and assets that are related to the presentation layer. If you have any classes that are only shared between presentation layer components such as UI element manipulation code, you can create a [Project-name].UI.Framework project to hold them in here.
  • [Project-name].UI.ProcessThis project should contain all the user interface process components (or controllers). Session, state management and page control classes should also reside here.
  • [Project-name].UI.Web This project should contain all the pages, scripts and user interface assets that will be deployed to the web server. This is the main entry point to the layered web application.

Services 
This folder should group all the projects and assets that are related to the service layer. All services related code whether they are ASMX, WCF or WEB API (REST), should reside in this folder. If you have any projects that extends the capabilities of the service technology, they should also reside in this folder.
  • [Project-name].ServicesThis project should contain all the WCF service implementation classes.
  • [Project-name].Services.Contracts This project should contain all the services and message contracts for the WCF services. For non-WCF services, this project can serve to hold wrapper classes for Request and Response message classes that are used for communication.
  • [Project-name].Services.HttpThis project should contain all the ASP.NET WEB API related service implementation classes. This project is not currently unfolded by LASG.

Shared 
This folder contains all the projects and assets that can be shared among any of the projects in the layers.
  • [Project-name].EntitiesThis project should contain all the entity classes that are shared among all other projects in the layer.
  • [Project-name].Framework This project should contain all the cross-cutting components such as Authentication, Authorization, Auditing, Logging, Configuration and etc.

Tests 
This folder should contain all the test projects for the components in the layers. You can create as many test projects in here based on your testing needs.
  • LeaveSample.TestThis project is created for you to place your tests (unit test, load test, web tests etc.).

This is how everything it looks like in Solutions Explorer. I have omitted some of the non-essential folders such as Scripts and Solution Items from the explanation.


What if I have multiple modules?

The above structure is simple when we are building a medium size application but how do we go about partitioning our projects when the applications becomes larger? There are two approaches that we can adopt.

Partition by Layer

The most common approach would be to partition the projects by layer. Each layer will contain the projects belonging to each module. Visual Studio provides the option to create Solution folders and you can use them to organize your projects neatly.


Take note that the Solution Folders aren't physical folders and if you want the physical folder structure to match the one shown in Solution Explorer, you will have to do it manually.

Partition by Module

The next approach is to partition all the projects into each Module's Solution Folder. I personally would recommend to use this approach as it allows you to selectively compile the entire module independently from the others. You can also selectively unload a particular module and keep yourself focused on the one that you are working on.


Can I have something simpler?

Frequently, Layered Architecture has been labelled as only suitable for large enterprise applications and overkill for smaller applications. This is understanding is inaccurate. Layered Architecture is an architecture pattern that should be inculcated in every business application developer, whether they are developing small or large applications.

The reason is that even the smallest business application has the potential to grow into something large or complex and Layered Architecture is merely a practice to logically partition the code. At the simplest level, we can still achieve layering with the following project structure.


The Entities project should be separated into a separate project for sharing reasons. This also applies if there is a Framework project available. Take note that the Contracts that is embedded inside the host will rely on Visual Studio's Add Service Reference dialog to re-create the service contracts on the presentation side. If a clean implementation is desired, the code in the contracts folder should also be separated into an individual project. LASG does not support this project structure.

You can check out the other posts in the series if you are interested to learn more about layering:

No comments:

Post a Comment

Popular Post