ASP.NET N-Layered Applications - Introduction (Part 1)

Note: this is part one in a series of ten. If you rather read this entire series off-line, you can buy the full series as a convenient PDF document that comes with the full source. Besides the convenience, buying the PDF will also make you feel good as it shows your appreciation for the articles and helps me pay the bills for my server and hosting so I can keep running imar.spaanjaars.com and continue to provide you with great content. For more details, check out this post that shows you how you can buy the entire series right now.

Now that the RTM versions of Visual Studio 2012 and .NET 4.5 have been out for a while, it seems like a good time to finally write the follow up to my popular series on N-Layered design using ASP.NET 3.5 that I wrote in 2008 and early 2009. I have been wanting to do this for a long time, but there were always other things on my Todo list with a higher priority. The wait has been worth it though; since the last series targeting .NET 3.5 that I published in late 2008 and early 2009, new and compelling technologies have been released that make writing an N-Layered application such as the Contact Manager a lot easier to write.

The following list has links to all articles in this series:

Introduction

In this new article series you'll see how to design and build an N-Layered ASP.NET application using ASP.NET MVC 4, ASP.NET 4.5 Web Forms and a number of other up-to-date technologies such as Entity Framework 5 and WCF. In this series, I'll build a sample application to manage contact people called the ContactManager v4.5 application, similar to the demo application demonstrated in the previous article series. Over the next 10 articles I'll dissect the sample application (that you can download at the end of each article, starting with Part 2) and show you how I designed and built it.

A big thanks to the people who reviewed tbis article and helped me find and fix issues in the text and code:

  • Ben Fox
  • Paul Hudson
  • Bart van Uden
  • Spiro Uyar

Your contributions have helped greatly in improving this article series. Many thanks!

Although you find full details in the remainder of this series, here’s a quick list of all the technologies and concepts I’ll be using for the ContactManager application.

  • Entity Framework (EF) 5 with Code First for all data access.
  • MVC 4, Web Forms 4.5, WCF and a command line tool for four different frontend implementations.
  • Unit and integration tests to make the model and application testable.
  • NuGet to quickly bring in additional libraries and assemblies.
  • FluentAssertions to make unit tests more straightforward to write and easier to read, especially for non-technical people.
  • A Dependency Injection (DI) framework called StructureMap to make it easier to program against interfaces and determine the concrete types at run time as well as improve the testability of your code.
  • A framework called AutoMapper to automatically map between your own domain objects and View Models in MVC and other applications.
  • DynamicQuery, a helper library from Microsoft to write string based LINQ expressions for sorting and filtering data.
  • FileHelpers, a third-party library to read CSV files which I’ll use in Part 9 to import data from a text file through the application’s API into the database.
  • NLog, a logging framework for .NET.

Why an N-Layered Architecture?

Using an N-Layered architecture for your ASP.NET applications brings a number of benefits, such as:

  • Separation of concerns - by putting code in separate layers, you separate the various parts of your application, such as data access, business logic and the UI. This makes it easier to design and build the application and makes it possible for developers in multiple
  • disciplines (database, server side programming, frontend development, design) to work on the application in parallel.
  • Abstraction - With a layered architecture it's easier to look at a complete application and understand the roles and responsibilities of individual layers and the relationship between them. Each layer has its own responsibilities which allows you to analyze them in isolation.
  • Testability - with a layered architecture, it's much easier to test each layer separately with unit tests as there are fewer dependencies between the various layers. This means, for example, that you can test your business logic or your UI without requiring a real database to test against.
  • Replaceability - It'll be easier to swap out layers. For example, you can replace your data access technology without affecting the other layers higher up in the stack.
  • Reuse - You can reuse one or more layers in different applications. You'll see the benefits of this in part 6 through 9 where the same data access and business layers are reused in four different frontend applications without requiring any changes to the lower layers.

Note that there is a big difference between N-Layers and N-Tiers. N-Layers deal with separate software layers and helps you group code logically within the application. N-Tiers on the other hand deals with the physical location of your software components: e.g. the machines where your code runs. This article series deals with N-Layer exclusively, although you could reuse much of it in an N-Tier application as well.

Introducing the Contact Manager Application

In this article series I’ll use the same sample application that I used in the previous article series: a simple contact manager application that enables you to manage your contacts and their contact data such as phone numbers and e-mail addresses. But rather than a single Web Forms demo application, the new sample solution has four different frontend applications: an ASP.NET MVC 4 web site, a Web Forms site, a WCF service project and a Command Line application.

When you start up one of the two web applications (the MVC or the Web Forms version) you see the home screen with a short welcome text. The People menu shows a list with all the contact people in the system with links to edit and delete them, and to manage their contact data:

The MVC site showing all contact people
Figure 1-1 The MVC site showing all contact people (click to enlarge)

When you click Edit you see the following page:

Editing a contact person in the MVC site
Figure 1-2 Editing a contact person in the MVC site (click to enlarge)

By clicking one of the address links for a contact person in the list with people (visible in Figure 1-1), you see a screen that lets you manage address details. Figure 1-3 shows the Web Forms version of the Edit address screen. The user has already pressed Save and the validation (from the Address class in the Model project) has kicked in:

Editing an Address in the Web Forms application
Figure 1-3 Editing an Address in the Web Forms application (click to enlarge)

When you click the Email addresses or Phone numbers link in the list of contact people, you see a list of associated contact details for that person:

Managing contact data in the Web Forms application
Figure 1-4 Managing contact data in the Web Forms application (click to enlarge)

From here, you can manage the existing data (edit and delete) as well as create new e-mail addresses for this contact.

The WCF project lets you execute CRUD (Create, Read, Update and Delete) methods against the contact people in the database over the network which is useful for machine-to-machine interactions.

Finally, the Command Line tool shows how to import data from a source like a CSV file to get existing data into the database through the application’s API.

As you can see, the functionality is rather simple which makes it easier to focus on the core concepts. However, when designing and building the sample application I haven’t taken any shortcuts or oversimplified things. Anything you see in the sample solution can be used to build real-world, large scale web applications.

History of the Contact Manager Application

This is the third version of the Contact Manager Application used to demonstrate N-Layer design concepts in ASP.NET. The first version was released in January 2007 and came as a single Web Site Project with all the UI, data access and business logic in a single project. The second version was released in November 2008. It introduced a Web Site Project for the UI as well as a number of class library projects for the business logic layer, the entities, the data access layer and the validation.

The previous design brought a lot of advantages in terms of separation of concerns and code that was relatively easy to understand and maintain. However, it did have a number of drawbacks that made it more difficult to use as I’ve learned in the past few years while building real-world web sites and applications based on this design. I’ll discuss these drawbacks in the next section. The solution to these drawbacks are discussed in the remainder of this article series.

Room for Improvement

Here’s a list of some of the issues that I ran into when building applications based on the previous design:

  • The solution required quite a lot of code in each of the layers. You needed code in the “dumb” data object, you needed a Manager class in the Business layer for validation of business rules, you needed a Manager class in the Data layer for database access and you needed quite a lot of code in stored procedures. Probably the biggest downside of this code is that most of it is repetitive, forcing you to write the same code over and over again for each of your implemented main entities.
  • Because of the tight coupling with the database layer, it was a challenge to test both the DAL and the code that uses the database layer, especially when used in other applications such as an ASP.NET MVC web site.
  • The solution required a lot of stored procedures, making maintenance and testing hard. For simple CRUD operations you needed at least four stored procedures (GetItem, GetList, InsertUpdateItem and DeleteItem) while you needed even more code to implement advanced scenarios such as filtering and sorting.
  • Adding members to the data entities was pretty difficult. Besides adding the member to a class in the BusinessEntities project, you also needed to add support for it in the various Manager classes and stored procedures. This meant lots of updates in lots of different places for something as simple as adding a new property.
  • The solution contained a lot of code to interact with the database. With the many ORM (Object Relational Mapping) systems available today, you really shouldn't have to write your own data access code anymore. For more information, check out: http://lostechies.com/jimmybogard/2012/07/24/dont-write-your-own-orm/.
  • The framework used its own validation mechanism. While this has served me (and others) well over the years, better alternatives are now available that make it easier to implement validation in your business entities. In addition, frameworks like ASP.NET MVC and Entity Framework (EF) have built-in support for this newer validation mechanism.
  • The application used an anemic design model, where business logic is implemented in separate classes that modify the state of your model objects. This is now considered an anti-pattern.

A Look Ahead

You’ll see how I am addressing these concerns in the new version of the application over the next 10 articles. To give you an idea of what to expect in this series, here’s a short summary of each of the 10 articles:

Part 1 - Introduction
In this article (which is what you’re reading right now), you’ll get a high-level overview of the architecture and see how I set up my projects, namespaces, classes etc. I’ll describe the purpose and responsibility of each of the main projects and how they work together.

Part 2 - Setting up the Solution in Visual Studio
In this article I’ll show you how to setup the solution using Microsoft Visual Studio 2012. I’ll show you how to organize your projects and solution on disk, and how to prepare the solution for integration with TFS so it allows for easy team development and branching.  I’ll show you how to use NuGet to add and maintain third party libraries in the projects.

Part 3 - Making your Project Unit Testable
This article shows you how to add unit test projects to your solution and how to set them up. I’ll be using a third party library called FluentAssertions to make your tests easier to write and understand.

Part 4 - Implementing a Model
In this article you’ll see how to set up the domain model for the application. It borrows heavily from the original application by reusing the main classes from the BusinessEntities project. This part focuses purely on the domain model, as interaction with the database is handled by a separate Visual Studio project that uses EF Code First, discussed in Part 5.

Part 5 - Implementing a Repository with Entity Framework 5 Code First
In this article you’ll see how to use Entity Framework 5 Code First to implement a data access layer that maps your model to an underlying (SQL Server) database. I’ll show you how to use the repository pattern to centralize data access code and make it available to other calling code. This article also talks about validation. Validation was a big feature of the 3.5 version of my framework, so it makes sense to implement it in the new version as well. You’ll see how to implement a validation strategy that is somewhat similar to the previous design in that it provides both property and object level validation. However, using built-in functionalities from the .NET Framework and the Entity Framework will make it much easier to implement the same validation in other applications such as an ASP.NET MVC site.

Part 6 - Putting it all together - Implementing an MVC 4 Frontend
In this article you’ll see how to implement an MVC 4 frontend using the model and repositories introduced in the earlier articles. The demo application enables you to manage contact people as well as their contact details such as addresses, e-mail addresses and phone numbers. You’ll see how to use Dependency Injection to inject the repository and other dependencies into the MVC controllers and how the controllers then use the repository to get data in and out of the database.

Part 7 - Putting it all together - Implementing a Web Forms 4.5 Frontend
In this article you’ll see how to implement an ASP.NET 4.5 Web Forms frontend using the model and repositories introduced in the earlier articles. The frontend of the application is almost the same as the MVC application, but now everything is implemented using ASP.NET 4.5 Web Forms and the new model binding capabilities introduced in ASP.NET 4.5.

Part 8 - Putting it all together - Implementing a WCF 4.5 Frontend
In this article you’ll see how to implement a WCF 4.5 service frontend using the model and repositories introduced in the earlier articles. The WCF service enables calling applications to retrieve contact people. In addition it also allows a calling application to create new and modify and/or delete existing contact people.

Part 9 - Putting it all together - Importing Data from the old Database using the API
This article shows you how to use the API of the application to import legacy data from an existing data source such as a CSV file. This serves as an example on accessing data using an application that has no UI and that just uses the application’s API.

Part 10 – Extensions, Tools and Wrapping Up
In the final part of the series I’ll show you some interesting tools that you can use when building applications like the ContactManager. I’ll also look at some extensions you could write and then summarize the full series.

Note: Part 2 and 3 of the series contain a lot of hands-on, step by step instructions as these articles show you how to setup a solution like the Spaanjaars.ContactManager application yourself. You can use these instructions pretty much as-is for your own applications. The remaining parts in the series then analyze the working code for the Spaanjaars.ContactManager application that you can download at the end of each article. I’ll show a lot of the code in detail, and explain how it works, but you won’t find detailed step by step instructions on how to add the code and files to the various projects.

Overview of the Architecture

In this section I’ll give you an overview of the complete application. You’ll see the main architecture, how I set up the various Visual Studio projects and how I linked them together. In addition you’ll see many of the important classes and other types inside each of the projects and learn about their responsibilities.

From a high level point of view, the architecture of the Spaanjaars.ContactManagerV45 solution looks as follows:

The architecture of the Spaanjaars.ContactManagerV45 Application
Figure 1-5 The Architecture of the Spaanjaars.ContactManagerV45 Application (click to enlarge)

The blue boxes at the bottom represent the data access layer, the green box in the middle represents the business layer and the orange boxes at the top represent the UI. The business layer also contains the model with all the main entities but that’s not shown in this diagram yet. You’ll see more of the model in Part 4.

At the bottom, you see a SQL Server database which is, just as in the previous series, the relational database used for the application. Above the database you can see the Entity Framework DbContext; the main class used for Entity Framework 5 Code First which is what I’ll use in this article series. Above this you can see a layer containing concrete repositories which use the Entity Framework DbContext internally. Note that this is just an implementation decision. The concrete repositories implement the interfaces defined in the green Repository Interfaces layer which means you can swap the concrete repositories and the Entity Framework for alternatives; for example you could build a concrete repository that uses NHibernate or Telerik’s OpenAccess ORM. The user interface applications that you see at the top of the diagram would never know you swapped the underlying data access technology as all they are aware of are the interfaces in the business layer. The exception to this is the command line application tool that you’ll see in Part 9 of this series. Since this application can be considered a one-off or “throw away” application, I haven’t bothered trying to decouple it from the concrete repositories that use EF.

You’ll see much more of this in the remainder of this series as I dig deeper into the various layers and explain how they are constructed.

From a Visual Studio perspective, the application looks as follows:

The Solution Explorer showing the Spaanjaars.ContactManagerV45 Application
Figure 1-6 The Solution Explorer showing the Spaanjaars.ContactManagerV45 Application

Notice how I used Visual Studio Solution Folders to group related project types (such as Tests and Frontend (UI) projects). This makes it easier to understand how the solution is organized and it helps you to quickly show or hide a particular group of projects you’re working with.

At the bottom of the Solution Explorer you can see three projects. The Spaanjaars.Infrastructure project contains a number of “plumbing” classes and interfaces used throughout the solution. The Spaanjaars.ContactManager45.Model project contains the core domain classes such as Person and Address and is somewhat similar to the BusinessEntities project from the 3.5 version of my N-Layer design. The Repositories.EF project contains all the code to interact with a SQL Server database using Entity Framework (EF) 5 Code First. Note that for the project names I use the pattern: Company.Project.Layer where Company is your company’s or your client’s name, Project is the name of the application and Layer specifies the type of project in the stack. You see more of this at the beginning of Part 2.

The Frontend folder contains four UI or frontend projects: one using ASP.NET MVC 4, one using ASP.NET Web Forms 4.5, one using WCF and a Command Line tool used for import of data. You’ll see these projects in later articles in this series. Under the hood, these projects make use of the various Model and Repositories projects.

The Tests Solution Folder contains a number of test projects for unit, integration and UI / MVC / WCF tests. These projects are discussed in Part 3.

This may look a little overwhelming, leading you to wonder why you need so many projects for a relatively simple application. If that’s the case, it’s important to realize you typically don’t need that many projects. In my sample application I have four different frontends, demonstrating N-Layer design in various types of applications. Also, for these projects I have separate test projects, quickly increasing the total number of projects. For my new design, the minimum number of projects you need is four: the three projects in the root of the solution explorer and at least one frontend application that uses these three projects.

To see how these projects relate to each other, consider the following model diagram that shows the dependencies of the two Web frontend and the WCF projects:

A model diagram showing various components of the Application
Figure 1-7 A model diagram showing various components of the Application (click to enlarge)

This figure shows how the Model project references the Infrastructure project, and nothing else (except for the .NET framework libraries of course which are not shown in this diagram.) The Repositories.EF project using Entity Framework (EF) references the Model project as well the Infrastructure project. The three Frontend projects (MVC, Web Forms and WCF) have a reference to the Model and Infrastructure projects as well as a reference to the Repositories.EF project. This latter reference isn’t strictly needed as all the code in the UI projects is based on interfaces defined in the Model project. Using a Dependency Injection framework such as Ninject or StructureMap you could inject the concrete types in the EF project at run-time, without any compile-time dependency on this project. However, I prefer to write the bootstrapper code (code that configures the Dependency Injection framework, discussed in detail in Part 6 and 8) in my project over configuration files, and so the UI projects each have a reference to the EF project. If I wanted to switch to a repository that uses another ORM such as NHibernate or other data access technology such as ADO.NET, all I would need to do is replace the project reference and rewrite the bootstrapper code. You’ll see more of this in part 5 when the EF Repository is implemented.

Although the details of the individual projects are discussed in great detail in the remainder of this article series, here’s an overview of how all the different projects work together:

  • The Model project defines all the core entities and their validation rules. Here you find classes such as Person and EmailAddress. You also find an IPeopleRepository which is an interface that defines the contract for working with Person objects. The types in the Model project are used by the UI projects. For example, the MVC project uses Person to display information about people in the system, as well as accept modifications to those objects (Insert, Update and Delete). These types are not directly used by the UI (such as Views) but are converted to View Models as you’ll see later in the series.
  • The UI projects don’t directly access the database to get their data. Instead, they use repositories that in turn access the database. A repository makes it easier to centralize data access code and make it available to other calling code. In my application, the Model project defines the contract for the repository which is then implemented in the Repositories.EF project. This project uses Entity Framework under the hood to get data in and out of the database.
  • The MVC and other UI projects use a concrete PeopleRepository from the Repositories.EF project. However, they don’t have a hardcoded link to this class as that would make it both difficult to replace EF with another database technology and unit test your UI applications. Instead, the UI projects work with the IPeopleRepository interface, while a concrete EF implementation is supplied at run-time using a concept called Dependency Injection.
  • The Spaanjaars.Infrastructure project provides low-level plumbing services used by all the other projects.
  • The various test projects have references to other parts of the application they are testing. For example, the integration tests project has a reference to the Repositories.EF project as it accesses a real database during its tests.

The application makes use of the Repository pattern. For alternatives to this pattern, see:

I’ll discuss each of the projects in the Solution Explorer next. You’ll find a high-level overview here with pointers to other articles in the series for more in-depth information.

Spaanjaars.Infrastructure

This is a fairly simple project with only a few classes, shown in Figure 1-8:

The Solution Explorer for the Spaanjaars.Infrastructure project
Figure 1-8 The Solution Explorer for the Spaanjaars.Infrastructure Project

As you can tell from its name, this project isn’t directly tied to the ContactManager application, Instead, I placed it in the more general Spaanjaars.Infrastructure namespace (which could be your company name or other root level namespace you might use) so it can easily be reused across multiple projects. This project provides three plumbing interfaces that the rest of the application uses. Figure 1-9 shows the class diagram for this project:  

The class diagram of the Spaanjaars.Infrastructure Project
Figure 1-9 The Class Diagram of the Spaanjaars.Infrastructure Project (click to enlarge)

The IRepository interface defines the contract that concrete repositories need to implement. It defines the members you interact with to get data in and out of the underlying data source. You’ll see an implementation of this interface along with the unit of work related interfaces in Part 5 when you see how to build a concrete repository using Entity Framework. It’s easy to build your own repository that targets a different database or ORM. All it needs to do is implement this interface and then you can plug it into another application such as a public facing ASP.NET MVC website.

DomainObject<T> and ValueObject<T> are the base classes for the various domain classes in the Model project. DomainObject<T> is the base class for entities that have an identity and is used by classes such as Person. ValueObject<T> is used by pure value objects that don’t have their own identity. In the sample application, Address has been implemented as a ValueObject<T> to demonstrate the differences. You’ll see more of this in Part 3.

Finally, in Part 5 you’ll see what the types in the DataContextStorage folder are used for and learn about the lifetime of an Entity Framework object context.

Spaanjaars.ContactManager45.Model

The Model project is somewhat similar to the BusinessEntities project in the .NET 3.5 version of this application. It features the application’s core types such as Person, Address and PhoneNumber. It also features a number of collections as well as a few enumerations to define types of contact records and people, respectively. Here’s what the Solution Explorer for the project looks like:

The Solution Explorer for the Spaanjaars.ContactManager45.Model project
Figure 1-10 The Solution Explorer for the Spaanjaars.ContactManager45.Model Project

Notice the four core types: Address, EmailAddress, Person, and PhoneNumber. If you’ve read the previous article series, these should all look familiar (except that Person was previously called ContactPerson). For the sake of demonstration, I let Address inherit from ValueObject<T> which means it’s considered a value type while all other classes inherit from DomainObject<T>. These last three types also have a collection counterpart that inherits from the custom, generic CollectionBase<T> type.

The IPeopleRepository interface provides a contract that the other applications in the project work against. You’ll see a lot more of this in Part 4 and 5 of this article series.

Figure 1-11 shows the complete Class Diagram for the Model project. In later articles in this series I’ll dig deeper into the various types and their members.

The class diagram of the Spaanjaars.ContactManager45.Model project
Figure 1-11 The Class Diagram of the Spaanjaars.ContactManager45.Model Project

You see more of the repositories in the next section, while a detailed explanation of the EF implementation can be found in Part 5 of this article series.

Spaanjaars.ContactManager45.Repositories.EF

This project contains all the implementation for working with contact people in a SQL Server database using Entity Framework 5 Code First. Figure 1-12 shows the Solution Explorer for this project.

The Solution Explorer for the Spaanjaars.ContactManager45.Repositories.EF project
Figure 1-12 The Solution Explorer for the Spaanjaars.ContactManager45.Repositories.EF Project

This project contains concrete implementations of the repository and unit of work related interfaces you saw earlier. In addition, it contains a number of classes related to setting up the Entity Framework, and initializing and configuring the database using the fluent API and database creating strategy classes. You see how all of this works when setting up Entity Framework in Part 5. For now, here’s the complete class diagram:

The class diagram for the Spaanjaars.ContactManager45.Repositories.EF project
Figure 1-13 The Class Diagram for the Spaanjaars.ContactManager45.Repositories.EF project (click to enlarge)

Spaanjaars.ContactManager45.Web.Mvc

This project contains the ASP.NET MVC 4 implementation of the frontend to work with contact people and their associated contact data in a web application. It’s discussed in detail in Part 6 of this article series. Here you’ll see Dependency Injection at work when the concrete repositories for the Entity Framework (or any other type you build) are injected into the application at run-time.

Spaanjaars.ContactManager45.Web.WebForms

This project contains the Web Forms implementation of the frontend to work with contact people and their associated contact data in a web application. It’s discussed in detail in Part 7 of this article series.

Spaanjaars.ContactManager45.Web.Wcf

This project contains a WCF service to work with contact people in your system over remote services. The WCF service has methods to retrieve, add, update and delete people from the system. The WCF project is discussed in detail in Part 8 of this article series.

Spaanjaars.ContactManager45.Import

This project contains a command line tool that can import contact people and their contact data from a CSV file. The purpose of this project is to demonstrate how to use the application’s public API from other applications. Part 9 of this series shows how I built the import tool.

In addition to the core libraries and the four frontend projects, the solution contains four test projects, nicely grouped together under a Solution folder called Tests. You will see how to set up the test projects in Part 3. Tests are then added to these projects in the remainder of the articles.

Spaanjaars.ContactManager45.Tests.Unit

This project contains unit tests for the solution. You’ll find some basic tests for the entities and their members, tests for validation, and more. Part 3 of this series digs deeper into this project.

Spaanjaars.ContactManager45.Tests.Integration

Since this application relies heavily on a database, it makes sense to have a number of integration tests that make use of the database. This way, you can test the interaction of the various components, as well as some database specific logic such as unique constraints. Once again Part 3 of this series digs deeper into this project.

Spaanjaars.ContactManager45.Tests.Frontend.Mvc

In this project you’ll find a number of tests for the ASP.NET MVC frontend. While the purpose of this article is not to show you how to write unit tests for MVC or other application frameworks, the tests in this project serve to demonstrate that with the framework presented in this series, unit testing is easy because of the way you can inject concrete types using a Dependency Injection framework while your application programs against an interface. This makes it much easier to test your controllers that have dependencies on components such as repositories.

Spaanjaars.ContactManager45.Tests.Frontend.Wcf

In this project you find a number of tests for the WCF services project. Just as with the MVC project, I am using Dependency Injection to decouple the service methods from their dependencies such as repositories to enable unit testing.

This article series is meant as an introduction to architecting N-Layered web applications using ASP.NET 4.5 and Entity Framework 5 Code First. This means I’ll dig as deep into these technologies as appropriate to explain the topic. However, it also means I won’t provide a lot of details about side issues. For example; I may be using an open source framework to make unit testing easier in the sample application, but I won’t dig into the details on how to retrieve and install this framework, or how to configure it for the sample application and how to use it.

Stuff I Like to Do

At the end of each article, I’ll provide a section called Stuff I Like to Do where I mention a number of asides and provide links and guidance where appropriate. For this first article, there’s nothing to add yet, other than maybe a suggestion to read Part 1 of the original article series at http://imar.spaanjaars.com/476/n-layered-web-applications-with-aspnet-35-part-1-general-introduction so that you have a general idea of how the application was designed previously.

Summary

In this article, you saw a brief overview of the ContactManager v4.5 application. I described some of the application’s history, and highlighted some shortcomings of the .NET 2.0 and 3.5 versions of the application. You then saw an overview of the new framework including the various components (Visual Studio projects) that are involved. The article concluded with a description of each project in the solution so you can see what their responsibilities are and how they fit together. Each of these projects is discussed in more detail in later parts of this article series.

In the next part, you’ll see how to setup the solution in Visual Studio. You’ll see how to add the Class Library projects and four Frontend projects (an MVC 4 site, a Web Forms application, a WCF service and a command line tool) to the solution. I’ll be using all of these projects in the remaining articles in this series.

Downloads


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Sunday, June 30, 2013 7:41:59 PM Mostafa said:
Hi Imar, Looks nice .
Long time ago , I followed your N-Layered design using ASP.NET 3.5 article series . that was so useful to me , I'm sure these are even better , Look forward for the next part .
On Sunday, June 30, 2013 7:54:11 PM Imar Spaanjaars said:
Hi Mostafa,

>> I'm sure these are even better

Let's hope so ;-) I am very pleased with the result, but welcome any feedback you may have.

Cheers,

Imar
On Sunday, June 30, 2013 10:53:22 PM Ben Oj said:
Hi Imaar, I find your N-Layered applications very useful and I am looking forward to this new series. I have built a few applications using your architecture in the previous serious and they work so well.

There is a lot of fuss about the repository pattern at the moment so it will be nice to see its benefits in this series.
On Monday, July 01, 2013 8:09:06 AM Statia said:
Hi Imar,

I'm really looking forward to this series of articles. I've been following your N-Layer articles since your first iteration in .Net 2.0.

Is there a subscribe mechanism or any way to get notified when each of the subsequent articles are published?
On Monday, July 01, 2013 8:13:06 AM Murat said:
Finally! I Build many apps with the help of previous articles (2008), and it's time to update :)

A Quick question. With this architecture can i eliminate EF Layer and use DAL with Stored Procedure like previous articles? Is this possible?
On Monday, July 01, 2013 10:20:56 AM Imar Spaanjaars said:
Hi Statia,

You can follow me on Twitter (@ImarSpaanjaars) where I announce new articles. You can also subscribe to my RSS feed at http://imar.spaanjaars.com/rss/

And if you don't want to wait: you can buy the full series now at http://imar.spaanjaars.com/587/new-article-series-on-aspnet-45-n-layered-design-now-available-for-purchase for only $20.

Imar
On Monday, July 01, 2013 10:23:10 AM Imar Spaanjaars said:
Hi Murat,

Yes you can, to some extent. You'll lose some of the power that EF brings (saving changes through a unit of work, complex search queries etc.) but you can certainly implement the repositories using plain ADO.NET that execute stored procedures. As an alternative, you can use the latest versions of EF that can use stored procedures under the hood.

Cheers,

Imar
On Tuesday, July 02, 2013 8:24:20 AM rahman mahmoodi said:
Hi,

Just by looking at your architecture diagram (fig 1.5), seem like there is a missing layer - business object layer?

On Tuesday, July 02, 2013 8:28:48 AM Imar Spaanjaars said:
Hi rahman,

Take a look at the note directly below the diagram:

"The blue boxes at the bottom represent the data access layer, the green box in the middle represents the business layer and the orange boxes at the top represent the UI. The business layer also contains the model with all the main entities but that’s not shown in this diagram yet. You’ll see more of the model in Part 4."

Cheers,

Imar
On Tuesday, July 02, 2013 8:44:24 AM Imar Spaanjaars said:
Hi rahman,

To avoid confusion, I just updated the diagram from Figure 1-5 to include the business layer.

Thanks,

Imar
On Monday, July 08, 2013 1:51:12 PM Paolo Vanini said:
Hi Imar, I've always learned a lot from your articles, so thank you! :-)
Looking into the code, I found that "DomanEntity" class accepts a generic parameter "K" as key/id. It's a nice solution, so you could use an int, a guid or a string for key/id but, unfortunatly, class "Repository" (and some of its methods) uses an hard-coded "int" parameter as key/id: so, if I create an domain entity whth a Guid as key, everything brokes up.
I tried to fix this issue on my own but I haven't found a solution. Could you help me, please?
On Monday, July 08, 2013 2:34:24 PM Imar Spaanjaars said:
Hi Paolo,

To change the model, you need to do the following:

Repository.cs change int => Guid
IPeopleRepository.cs change int => Guid
Person.cs: let Person inherit from DomainEntity of Guid

You'll also need to ensure that a new Guid is assigned automatically; either in the class constructor or at the database level.

Once that's done, you'll need to update all of the Frontend and unit test code to use a Guid for a person's ID instead of an int.

The reason for this implementation is that DomainEntity can be used in any project type, and I don't want to enforce the type there. However, in the actual implementation (In Repositories.EF), I know my domain and can pick an int (or a Guid) and use that throughout the application. That's why I decided to lock the type in the Repository base class to an int.

Cheers,

Imar
On Monday, July 08, 2013 3:18:48 PM Paolo Vanini said:
Thanks for the answer! :-)
It's fine but, in that way, every key/id in the domain should be of only one type (be it an integer, guid, string, etc).
I'd like to create a solution to use different types of id.
Using your code as an example, I'd like to use a guid for "Person" and an int for "PhoneAddress" but in a domain contest, I could/would use a different type of id for every aggregate root.
The problem I can't solve is in the "FindById" method in "Repository" class.
I could pass a generic parameter "K id" instead of a "int id" but I don't know how to use it inside the query with the "include properties" parameter. Maybe is just a problem of finding the right syntax but it's over my knowledge...
On Monday, July 08, 2013 5:55:47 PM Paolo Vanini said:
I found a possible solution but this comment form doesn't accept the code (it thinks is contains some kind of weird html).
I sent you a mail and I'd really apprecciate your opinion about it.
Thanks again and keep writing interesting posts!
On Tuesday, July 09, 2013 4:06:30 AM Vladimir Kelman said:
Hi Imar,

It looks like a great opportunity to follow you in your new implementation of N-Layer design.
We based a structure of our company's (COmputing TechnologieS, Inc)  Intranet on your previous articles. It served well.

Of course we made a some changes to your design. For example, we found that in a real and big project using custom collection classes for for collections of business objects creates too many unnecessary collection classes and takes away some flexibility. So, in most cases we used IEnumerable[T] / List[T] classes to represent our collections. In some cases extension methods came handy.  (Your site's commenting system does not allow to include angle braces into comments)

Another thing I'm not sure of is adding Date Created / Date Modified fields to Model classes (e.g Person) and corresponded database tables. In my opinion, these fields (along with CreatedBy / ModifiedBy) do not represent properties of domain objects, but rather belong to infrastructure (tracking is an external concerns).  So, in a real-world application it may be better to have a separate project dealing with this tracking functionality.

Looking forward for the next articles in your series.
On Tuesday, July 09, 2013 10:14:31 AM Imar Spaanjaars said:
Hi Vladimir.

Re: collections: yes, I think that makes sense. I like the flexibility that custom collections bring, but it isn't always necessary.

>> Your site's commenting system does not allow to include angle braces into comments

Yup, on purpose.

>> Another thing I'm not sure of is adding Date Created / Date Modified fields to Model classes (e.g Person) and corresponded database tables.

I think it depends. For some scenarios, it's model data and belongs on the model. In other case it may not belong to the model, but could be related to, for example, auditing, in which case an external solution makes sense indeed.

Cheers,

Imar
On Wednesday, July 10, 2013 5:46:44 AM KM said:
Hi Imar . I'm trying to build the solution for the first time in my Visual studio 2012 (professional). But, I'm getting the below error when I click the "People" menu.  I have both Sql Server and SQLExpress installed on this machine.  I'm sorry if the issue is mentioned somewhere in the articles that I haven't read yet. But, do you have any idea where should I look first for the below error message ?

Exception Details: System.Data.SqlClient.SqlException: CREATE DATABASE permission denied in database 'master'.

Source File: d:\Documents\Visual Studio 2012\Projects\NLayer45\Applications\Spaanjaars.ContactManager45.Web.WebForms\People\Default.aspx.cs    Line: 13


[SqlException (0x80131904): CREATE DATABASE permission denied in database 'master'.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +1769462
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)  +5318578
  
On Wednesday, July 10, 2013 7:43:11 AM Imar Spaanjaars said:
Hi KM,

You can try two things:

1. Move the entire solution out of your Documents folder (e.g. to C:\Samples). SQL Express may not have permissions to create the database at the current location.

2. Download the most recent version of the source from here: http://imar.spaanjaars.com/Downloads/Articles/N-Layer_Design_45/NLayer-4.5.0.0-Source.zip

A few days ago I made a small change to the source that sets LocalDB as the default database engine for the application.

Hope this helps, and please let me know if it doesn't.

Cheers,

Imar
On Wednesday, July 10, 2013 2:58:41 PM KM said:
Thanks Imar ! That solved the problem. I believe it's the latest source code that solved it.
On Thursday, July 11, 2013 1:55:32 PM Scott Baldridge said:
Hello Imar! Thanks for the Article!

I'm at the point where we add the solution to TFS. I have a TFS account and created a project in TFS. The project in TFS is named WYW.ContactManager. The solution is named G:\Work\WYW.ContactManager

I have connected to TFS and right click on the solution and select add solution to source control. In the Team Project Location I get the following error:
Could not find a part of the path 'J:\Work\WYW.ContactManager\Main\$tf'.

How can I fix this issue?
On Thursday, July 11, 2013 1:59:37 PM Imar Spaanjaars said:
Hi Scott,

Did you create the SLN file and all of the projects under the same location as in my example?

The $tf reference is a folder where TFS stores local files. Maybe you already mapped that folder or its parent (Work) to a different folder in TFS? To find out, open the Source Control Explorer and from the Workspace drop-down choose Workspaces... Then make sure your mappings are valid and are pointing to the locations you expect them to.

Cheers,

Imar
On Thursday, July 11, 2013 2:34:06 PM Scott Baldridge said:
Thanks! That did the trick.
On Friday, July 12, 2013 2:41:53 PM Scott Baldridge said:
Hello Imar,

I'm in part three and setting up the initial test for tests.frontend.Mvc.HomeControllerTests.

I have an error on this line:
var result = controller.Index() as ViewResult;

The error is:
The type or namespace name "ViewResult" could not be found(are you missing a using directive or an assembly reference?

I have checked the using directives and the references are correct as well.

Did I miss something?

On Saturday, July 13, 2013 11:00:55 AM Imar Spaanjaars said:
Hi Scott,

Maybe you missed the reference to System.Web.Mvc in the table with references in Part 3? By referencing that assembly, you bring the MVC functionality in scope.

Then in order to use ViewResult, you need a using statement as well like this:

using System.Web.Mvc;

Hope this helps,

Imar

On Thursday, July 18, 2013 8:53:53 AM @bhitalks said:
Hi Imar,

Thanks a lot for this series. I have read your earlier series and benefited greatly. In fact, now for all of my projects I used the same architecture as in your 3.5 series. Yes, it entails a lot of repetitive code and I find myself stuck sometimes on really big projects, but this has served me well.

When you say that the model/pattern is now considered an anti-pattern, what does it mean? So, all my projects are now not a best practice any more? Can I not continue using the same pattern?

Thanks a lot.
-Abhi
On Monday, July 22, 2013 2:05:38 AM Vladimir Kelman said:
Imar, thank you for providing a link to articles about DDD by Jak Charlton. They are excellent, short and clear introduction to DDD. I just read his DDD: The Repository Pattern article and found that even in 3.5 version of your N-Layer design series you implicitly used something very close to DDD Repository pattern, although it was called DAL. It had, as Jak said, a IList type of interface and was good in isolation from actual database, rather than talking in terms of data rows.
On Monday, July 22, 2013 2:18:28 AM Vladimir Kelman said:
To Paolo Vanini.

Paolo, could you show me how did you modify Repository class to make it use a generic type for Id?  My email is vkelman  at gmail.

  Thanks
On Monday, July 22, 2013 6:08:56 PM Paolo Vanini said:
To Vladimir Kelman:
I've sent you my solution.
I'll publish on this website when part 5 of Imar's articles will be online.
On Sunday, July 28, 2013 7:16:15 PM Imar Spaanjaars said:
Hi bhitalks,

You can certainly continue using the same practices. However, the software landscape has changed a lot in the last 5 years and this new series addresses the new world. By using the new practices, you can create software that will be easier to create, test and maintain, now and in the future. I would recommend reading the new series and then determine whether you want to adopt these new practices or not.

Cheers,

Imar
On Monday, July 29, 2013 5:51:39 AM Saroop Trivedi said:
Hello Imar,
I am happy to replied on my old comment for framework 3.5 implementation. I try to open your code into VS2010. But Unfortunately it's not open. I tried all way to open. Please make your code compatible with VS2010.

1.I was install framework 4.5
2.Try to reload all .csproj file again,But not able to open...

Please do needful.
On Monday, July 29, 2013 2:54:12 PM Imar Spaanjaars said:
Hi Saroop,

In order to build .NET 4.5 applications you need Visual Studio 2012. VS 2010 won't work.

Cheers,

Imar
On Thursday, October 31, 2013 1:12:46 PM Angelo said:
Hello Imar,

Once again thank you for an excellent sample, what I was really interested in was looking at the data entry forms and seeing how they could be converted to user controls, I tried doing that but the ModelState.AddModelError(error.MemberNames.FirstOrDefault() ?? "", error.ErrorMessage); does not work when it is within a user control context and not a page.

Any ideas on that? Or perhaps you can add one example of doing the dataentry Edit a Person using a user control?
On Thursday, October 31, 2013 1:36:46 PM Imar Spaanjaars said:
Hi Angelo,

Given that a UC does not have a ModelState property, I think the solution could be to create a property on the UC that returns the validation errors which is then accessed by code in the page class. Alternatively, the UC could use this.Page.ModelState to communicate errors with the container page directly.

Cheers,

Imar
On Saturday, November 23, 2013 2:31:34 AM Kangi said:
Hi,

Is it safe to not dispose DbContext in asp.net requests?

JK
On Sunday, November 24, 2013 7:15:01 AM Imar Spaanjaars said:
Hi Kangi,

It'll go out of scope when HttpContext goes out of scope.

However, the Repository base class that wraps the DbContext implements IDisposable so if you call Dispose on a repository or use it in a using statement, the DbContext is disposed off as well.

Cheers,

Imar
On Tuesday, December 03, 2013 8:36:36 PM Abdu said:
The zip file creates zero length App_Data files instead of App_Data empty folders. I had to delete these files and create the folders.
On Wednesday, December 04, 2013 1:37:13 PM Imar Spaanjaars said:
Hi Abdu,

That's odd. Which decompression tool do you use? It works fine for me using the compression tools built into Windows as well as with WinRar.

Cheers,

Imar
On Monday, February 24, 2014 2:10:22 PM Mubashir said:
Hi Imar..
why dont u make a vedio series of these articles.. that will be great as these articles..
On Monday, February 24, 2014 8:08:12 PM Imar Spaanjaars said:
Hi Mubashir,

If only there were 30 hours in a day.... ;-)

Imar
On Friday, March 07, 2014 3:14:08 AM Ricardo Gomez @Rickybonmx said:
Hi Imar. Great stuff you got here! Thank you very much.

I've seen several architectural design layers and the repository is only accessible by the domain layer.

How come you access the repository from the UI layers without going through the domain layer? Is it all right? It seems odd to me :S

Greetings from Mexico.
Sorry for my English if not correct. :)
On Friday, March 07, 2014 10:11:30 AM Imar Spaanjaars said:
Hi Ricardo,

You can easily add a domain or service layer in between that communicates with the repositories.

Cheers,

Imar
On Wednesday, May 07, 2014 4:19:46 PM uday said:
can I have your Skype id or facebook id
On Wednesday, May 07, 2014 6:01:25 PM Imar Spaanjaars said:
Nope, but you can follow me on Twitter if you want to keep in touch: @ImarSpaanjaars

Cheers,

Imar
On Monday, January 19, 2015 9:27:04 AM Robert said:
Hello Imar,

I installed your application and I'm beginning to try to understand its design.

One primary question: where is the database ?

Thanks

Robert
On Monday, January 19, 2015 12:36:20 PM Imar Spaanjaars said:
Hi Robert,

Take a look at part 5 that shows you how this works:

http://imar.spaanjaars.com/577/aspnet-n-layered-applications-implementing-a-repository-using-ef-code-first-part-5

The database is created against an instance of Local DB.

Cheers,

Imar
On Monday, January 19, 2015 3:24:04 PM Robert said:
Hello Imar,

you write that:  

1) DomainObject is the base class for business entities that have an ID, like Person.

2) ValueObject is the base class for business entities that do not have an ID like Address.

Why then the base class for EmailAddress and PhoneNumber is DomainObject ?

Thank you
Roberto
On Monday, January 19, 2015 4:23:13 PM Imar Spaanjaars said:
Hi Robert,

Take a look at part four where this is explained:

----
For this article series, I implemented Address as a ValueObject and the other two as entities. You could argue that PhoneNumber and EmailAddress are great candidates for Value Objects and I would fully agree. However, I want to implement these types as collections (so you can have multiple instances of each attached to a contact person). To implement this one to many relationship in EF, the other end (i.e. the PhoneNumber and the EmailAddress) needs to have its own identity (e.g. an Id property). That conflicts with the absence of an identity in a ValueObject, and as such PhoneNumber and EmailAddress are implemented as entities.
----

Cheers,

Imar
On Monday, March 02, 2015 10:36:52 PM Robert said:
Hi Imar,

is the "Repository pattern" also known with other terms ?
I can't find it in the well-known books on Design patterns.
Can you tell us where we could deepen our comprehension of it ?

Thanks
On Monday, March 02, 2015 10:47:55 PM Imar Spaanjaars said:
Hi Robert,

"Repository pattern" (between quotes) gives me 188000 results on Google; enough to sink your teeth in ;-)

Cheers,

Imar
On Tuesday, May 26, 2015 4:51:15 AM dinesh said:
do u have any 3 layered architecture example. it's very important to me now. if u have that stuff please share on my mail.
On Tuesday, July 07, 2015 11:47:30 AM chr1skol1 said:
Hi Imar,
fantastic and helpful article about the way to implement n-layered applications with ASP.NET.

Thanks and greetings
Christoph
On Wednesday, August 05, 2015 3:09:18 AM Leondez said:
Hi Imar,

This is the best pratical explanation of DDD. But, i also need an example of Service Domain. I try to find in google but i still dont get it.

Would you please to make it?

Thank You So Much.

Leo - Jakarta Indonesia
On Saturday, August 08, 2015 4:02:15 PM Imar Spaanjaars said:
Hi Leo,

I don't have any ready-made examples but I can highly recommend Scott Millett's Patterns, Principles, and Practices of Domain-Driven Design that shows this in detail: http://www.amazon.com/Patterns-Principles-Practices-Domain-Driven-Design/dp/1118714709/ref=sr_1_1?ie=UTF8&qid=1439049610&sr=8-1&keywords=scott+millett

It's easily the best book I've read on the subject.

Cheers,

Imar
On Monday, September 05, 2016 4:41:29 AM richard soe said:
Hi Imar,

I've been using your N-layer solution and it's working great.
Your sample is based on a single database.

I'm planning to add additional databases into the solution. Can you please advise what's the best way to achieve this?

Cheers.
On Monday, September 05, 2016 7:33:22 AM Imar Spaanjaars said:
Hi Richard,

It really depends on the reason you're bringing in different databases and what data they contain. You could create separate models and have each one target its own database if the two databases aren't really related.

if you need to update another database when something in one database changes  you could use different models to write to the various databases, or you could use a service bus like NServiceBus to send changes onto the bus to eventually be handled by the other database.

Not a simple question to answer as it all depends on your environment and requirements.

Cheers,

Imar
On Tuesday, September 06, 2016 8:51:21 AM richard soe said:
Hi Imar,

Thanks for your suggestion and quick reply.

I was planning to introduce 2FA service into the project solution and there is a need to put this into separate database.

The solution that you suggested seems to work but after thinking about it for the the long term it will get very complex and hard to manage, especially for my case, so I decided to create a separate web service project altogether so that it is easier to maintain for the long term.

Cheers!

On Wednesday, September 07, 2016 7:41:06 AM Imar Spaanjaars said:
Hi Richard,

yeah, I agree; a service layer makes a lot more sense and would be more flexible in the future.

Cheers,

Imar
On Tuesday, November 29, 2016 7:18:47 PM Don said:
What, if anything, would you say has changed considering all of the latest .NET Core releases?
On Tuesday, November 29, 2016 10:46:44 PM Imar Spaanjaars said:
Hi Don,

The core concepts are still the same. However, the implementation will be really different. EF has changed, .NET now has built-in dependency injection capabilities, the tooling has changed, just to name a few.

Cheers,

Imar
On Wednesday, November 30, 2016 4:28:04 PM Don said:
Sounds like a perfect time for an update to address the latest and greatest :)
On Wednesday, November 30, 2016 4:32:44 PM Imar Spaanjaars said:
Absolutely. I just wished I had the time to do it....

Imar

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.