Upload
theeranit-pongtongmuang
View
346
Download
5
Embed Size (px)
Citation preview
BuildingN-LayeredApplications
withASP.NET4.5
2013 - Imar Spaanjaars http://imar.spaanjaars.com
Dear reader,
Thank you for buying my article series Building N-Layered Applications with ASP.NET 4.5.
Thanks to your support I can continue to run http://imar.spaanjaars.com and add fresh
content as often as possible.
If you run into problems with the article or the code presented in it, you have a few
different options:
1. First, try posting your question at the end of one of the articles on my site that deals
with your question using the Talk Back feature at the bottom of the page. This is the
best solution as others will be able to join and learn from the discussion as well. You
find the full article series here: http://imar.spaanjaars.com/573/aspnet-n-layered-
applications-introduction-part-1.
2. If you have a question you dont want to share with the community, use the Contact
page on my website at: http://imar.spaanjaars.com/contact. Before you post there,
please consider whether your question isnt much better off posted at the end of
one of the articles. This makes it easier for me to answer it only once, and refer
others to the answer if they have the same question.
3. Finally, you can send an e-mail to [email protected]. I typically try to answer e-
mail within 2 or 3 business days, but please allow for a longer time in some cases.
I hope youll enjoy reading this series as much as I enjoyed writing it. If you have any
questions or feedback (good or bad), use the contact options I described above. I love to
hear what you think of this series.
If you havent bought this series, but got it from a friend, a colleague or elsewhere, please
consider buying the series through my website at http://imar.spaanjaars.com/587/new-
article-series-on-aspnet-45-n-layered-design-now-available-for-purchase. Its not expensive,
and by buying the series, you help me to keep run http://imar.spaanjaars.com.
Have fun and happy N-Layering!
Imar Spaanjaars
ASP.NET N-Layered Applications - Introduction (Part 1)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 (1)
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.
IntroductionIn 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.
Although you find full details in the remainder of this series, heres a quick list of all the technologies and concepts Ill
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 (2)
to quickly bring in additional libraries and assemblies.
FluentAssertions (3)
to make unit tests more straightforward to write and easier to read, especially for
non-technical people.
A Dependency Injection (DI) framework called StructureMap (4)
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 (5)
to automatically map between your own domain objects and View Models
in MVC and other applications.
DynamicQuery (6)
, a helper library from Microsoft to write string based LINQ expressions for sorting and
filtering data.
FileHelpers (7)
, a third-party library to read CSV files which Ill use in Part 9 to import data from a text file
through the applications API into the database.
NLog (8)
, 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 application
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
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 1 of 162
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 ApplicationIn this article series Ill 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:
(9) See Links in this Document at the end for the full URL of this image.
Figure 1-1 The MVC site showing all contact people
When you click Edit you see the following page:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 2 of 162
(10) See Links in this Document at the end for the full URL of this image.
Figure 1-2 Editing a contact person in the MVC site
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:
(11) See Links in this Document at the end for the full URL of this image.
Figure 1-3 Editing an Address in the Web Forms application
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 3 of 162
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:
(12) See Links in this Document at the end for the full URL of this image.
Figure 1-4 Managing contact data in the Web Forms application
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 applications 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 havent 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 ApplicationThis 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 Ive
learned in the past few years while building real-world web sites and applications based on this design. Ill discuss
these drawbacks in the next section. The solution to these drawbacks are discussed in the remainder of this article
series.
Room for ImprovementHeres a list of some of the issues that I ran into when building applications based on the previous design:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 4 of 162
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 may 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 (13)
, 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 AheadYoull 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, heres a short summary of each of the 10 articles:
Part 1 - Introduction
In this article (which is what youre reading right now), youll get a high-level overview of the architecture and see how
I set up my projects, namespaces, classes etc. Ill 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 Ill show you how to setup the solution using Microsoft Visual Studio 2012. Ill 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. Ill 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. Ill 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 youll 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 youll 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. Ill 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. Youll 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 youll 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. Youll 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
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 5 of 162
of the database.
Part 7 - Putting it all together - Implementing a Web Forms 4.5 Frontend
In this article youll 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 youll 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 - Import Tool - 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
applications API.
Part 10 Extensions, Tools and Wrapping Up
In the final part of the series Ill show you some interesting tools that you can use when building applications like the
ContactManager. Ill 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. Ill show a lot of the code in
detail, and explain how it works, but you wont find detailed step by step instructions on how to add the code and files
to the various projects.
Overview of the ArchitectureIn this section Ill give you an overview of the complete application. Youll see the main architecture, how I set up the
various Visual Studio projects and how I linked them together. In addition youll 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:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 6 of 162
(14) See Links in this Document at the end for the full URL of this image.
Figure 1-5 The Architecture of the Spaanjaars.ContactManagerV45 Application
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 thats not shown in this diagram yet. Youll 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 Ill 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 Teleriks 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 youll see in Part 9 of
this series. Since this application can be considered a one-off or throw away application, I havent bothered trying to
decouple it from the concrete repositories that use EF.
Youll 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:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 7 of 162
Figure 1-6 The Solution Explorer showing the Spaanjaars.ContactManagerV45 Application
Notice how I used Visual Studio Solution Folders (15)
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 youre 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 companys or your clients 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. Youll 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 thats the case, its important to realize you typically dont 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:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 8 of 162
(16) See Links in this Document at the end for the full URL of this image.
Figure 1-7 A model diagram showing various components of the Application
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 isnt 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.
Youll 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, heres
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 youll see later in the series.
The UI projects dont 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 dont 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:
http://lostechies.com/jimmybogard/2012/09/20/limiting-your-abstractions/
http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/
Ill discuss each of the projects in the Solution Explorer next. Youll find a high-level overview here with pointers to
other articles in the series for more in-depth information.
Spaanjaars.Infrastructure
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 9 of 162
This is a fairly simple project with only a few classes, shown in Figure 1-8:
Figure 1-8 The Solution Explorer for the Spaanjaars.Infrastructure Project
As you can tell from its name, this project isnt 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:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 10 of 162
(17) See Links in this Document at the end for the full URL of this image.
Figure 1-9 The Class Diagram of the Spaanjaars.Infrastructure Project
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. Youll see an implementation of this interface
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 11 of 162
along with the unit of work related interfaces in Part 5 when you see how to build a concrete repository using Entity
Framework. Its 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 and ValueObject are the base classes for the various domain classes in the Model project.
DomainObject is the base class for entities that have an identity and is used by classes such as Person.
ValueObject is used by pure value objects that dont have their own identity. In the sample application, Address
has been implemented as a ValueObject to demonstrate the differences. Youll see more of this in Part 3.
Finally, in Part 5 youll 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 applications 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. Heres what the
Solution Explorer for the project looks like:
Figure 1-10 The Solution Explorer for the Spaanjaars.ContactManager45.Model Project
Notice the four core types: Address, EmailAddress, Person, and PhoneNumber. If youve 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 which means its considered a value type while all other
classes inherit from DomainObject. These last three types also have a collection counterpart that inherits from the
custom, generic CollectionBase type.
The IPeopleRepository interface provides a contract that the other applications in the project work against. Youll 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 Ill dig deeper into
the various types and their members.
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 12 of 162
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 13 of 162
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.
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, heres the complete class diagram:
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 14 of 162
(18) See Links in this Document at the end for the full URL of this image.
Figure 1-13 The Class Diagram for the Spaanjaars.ContactManager45.Repositories.EF project
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. Its discussed in detail in Part 6 of this article series. Here youll 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. Its 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.
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 15 of 162
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 applications 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. Youll 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 youll 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 Ill dig as deep into these technologies as appropriate to explain the topic.
However, it also means I wont 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 wont 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 DoAt the end of each article, Ill 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, theres 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.
SummaryIn this article, you saw a brief overview of the ContactManager v4.5 application. I described some of the applications
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, youll see how to setup the solution in Visual Studio. Youll 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. Ill be using all of these projects in the remaining articles in this series.
Links in this Document(1) http://imar.spaanjaars.com/476/n-layered-web-applications-with-aspnet-35-part-1-general-introduction
(2) http://nuget.org/
(3) http://fluentassertions.codeplex.com/
(4) http://docs.structuremap.net/
(5) http://automapper.org/
(6) http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 16 of 162
library.aspx
(7) http://filehelpers.sourceforge.net/
(8) http://nlog-project.org/
(9) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01/Figure1-01_MVC_People_list.png
(10) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01/Figure1-02_MVC_Edit_Person.png
(11) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01/Figure1-03_WebForms_Edit_Address.png
(12) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01
/Figure1-04_WebForms_EmailAddresses.png
(13) http://en.wikipedia.org/wiki/Anemic_domain_model
(14) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01/Figure1-05_Solution_Architecture.png
(15) http://msdn.microsoft.com/en-us/library/vstudio/sx2027y2%28v=vs.100%29.aspx
(16) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01/Figure1-07_DependencyGraph.png
(17) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01
/Figure1-09_Spaanjaars.Infrastructure_Classdiagram.png
(18) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part01
/Figure1-13_Spaanjaars_Repositories_EF_ClassDiagram.png
ASP.NET N-Layered Applications - Introduction (Part 1)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 17 of 162
ASP.NET N-Layered Applications - Setting up the Solution in
Visual Studio (Part 2)This is Part 2 in a series of 10 that show you how to build N-Layered applications using ASP.NET 4.5 and Entity
Framework 5 Code First. The previous article provided some history of the architecture of the Contact Manager
application and gave a broad overview of the new architecture. In this installment, things get a bit more concrete
when you see how to setup a solution in Visual Studio 2012. The VS solution is going to contain three class libraries:
one for the Infrastructure, one for the applications Model and one to hold the Entity Framework (EF) Repository
implementation. Ill also add four frontend projects (an ASP.NET MVC 4, a Web Forms project, a WCF service project,
and a windows command line application) which are discussed in detail in Part 6, 7, 8 and 9 of this series respectively.
In the next article in this series Ill extend the solution with four more projects for unit, integration, UI and service
tests.
Note: as mentioned in Part 1 (1)
, this article and the next article (Part 3 (2)
) contain a lot of hands-on, step by step
instructions that show you how to setup a solution like the Spaanjaars.ContactManager application. You can use these
instructions pretty much as-is for your own applications. The remaining parts in the series analyze the working code
for the Spaanjaars.ContactManager application. Ill show a lot of the code in detail, and explain how it works, but you
wont find detailed step by step instructions on how to add the code and files to the various projects. Instead, you're
encouraged to download the code at the end of each article to see how it works.
Naming ConventionsIf youve read the previous article series, youll recognize the naming conventions I use for my projects and root
namespaces. For the main projects I use the pattern: Company.Project.Layer where Company is your companys or
your clients name, Project is the name of the application and Layer specifies the type of project in the stack. I can
further divide the layer in specific project types. This gives me names such as Spaanjaars.ContactManager45.Model
and Spaanjaars.ContactManager45.Web.Mvc.
My test projects follow the same pattern for the root name and are then further divided in the type of tests (Unit,
Integration etc.) leading to names such as Spaanjaars.ContactManager45.Tests.Unit.
Note that the Infrastructure project I introduced in the preceding article is independent of the ContactManager
application and can be reused across multiple applications. As such, its called Spaanjaars.Infrastrucure rather than
Spaanjaars.ContactManager45.Infrastrucure.
Setting up the SolutionIn the following section youll find detailed instructions on setting up the solution. This is useful if you want to create
your own project from scratch. If you just want to see the sample code or run the application, you can skip all these
steps and simply open the solution that comes with this article series in Visual Studio 2012. You find a link to the
source code at the end of each article.
Note: these steps are heavily borrowing from an earlier article I wrote about setting up a project for team
development and TFS (3)
. I decided to repeat part of the steps here and make them more specific for the
Spaanjaars.ContactManager application.
Start Visual Studio 2012 and choose File | New Project.1.
At the top of the dialog, choose .NET Framework 4.5 from the drop-down list.2.
In the Other Project Types category click Visual Studio Solutions and then click Blank Solution. As the name of
the Solution, enter Spaanjaars.ContactManager45 and as the Location choose C:\Projects. Note: substitute
Spaanjaars and ContactManager with your own company and project names.
3.
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 18 of 162
(4) See Links in this Document at the end for the full URL of this image.
Figure 2-1 The New Project Dialog in Visual Studio 2012
Click OK.4.
Close Visual Studio and open the project folder (at C:\Projects\Spaanjaars.ContactManager45) in File
Explorer (Windows Explorer on Windows 7 and earlier). Create a new folder called Main and then drag all of
the Spaanjaars.ContactManager45.* files from C:\Projects\Spaanjaars.ContactManager45 into this new
Main folder. Your structure now looks like this:
5.
(5) See Links in this Document at the end for the full URL of this image.
Figure 2-2 File Explorer Showing the Solution
This Main folder is used later for Branching in TFS. This all feels a bit clumsy but I see no other way to create the
solution with this name and store it in a folder called SolutionName/Main. Fortunately, this is a one-time operation.
Open the Solution in Visual Studio by double-clicking the .sln file in the Main folder.6.
Right-click the Solution in the Solution Explorer and choose Add | New Project.7.
In the tree on the left choose your programming language, and then choose Class Library from the Windows8.
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 19 of 162
category.
At the top of the dialog, make sure that .NET Framework 4.5 is selected.9.
As the name of the project, enter Spaanjaars.ContactManager45.Model.10.
As the location for the project enter C:\Projects\Spaanjaars.ContactManager45\Main\Applications:11.
(6) See Links in this Document at the end for the full URL of this image.
Figure 2-3 The Add New Project Dialog for the Model Project
Notice the inclusion of the Applications folder in the path. This way you can group all projects that make up the core
application in a single folder. In the next article Ill use a folder called Tests inside the Main folder to group all Test
projects.
Click OK to add the project.12.
On disk, your solution now has the following structure:13.
(7) See Links in this Document at the end for the full URL of this image.
Figure 2-4 File Explorer Showing the Model Project
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 20 of 162
Back in Visual Studio, delete the default Class1.cs file as you dont need it.14.
Repeat steps 7 through 12 and 14 two more times and add the following Class Library projects:Spaanjaars.ContactManager45.Repositories.EF1.
Spaanjaars.Infrastructure2.
15.
Make sure you dont forget the \Applications part in the projects location, as VS defaults to the solutions folder
instead.
Note that the Infrastructure project is generic enough to be placed in a namespace which is outside the
ContactManager application. This makes it possible to reuse the classes defined in this project in other solutions based
on the same model. For this sample application I put the project in the Applications folder, but if youre reusing it
across multiple projects youll want to store it elsewhere such as in C:\Projects directly.
In the next section youll see how to add four frontend projects to the solution. In your own projects you dont need all
four of them; just pick the one(s) you need. If you want to follow along with this series, just add all four projects.
Right-click the Solution in the Solution Explorer and choose Add | New Solution Folder. Name the folder
Frontend.
16.
The next steps show you how to add an ASP.NET MVC 4 application to the solution. If you prefer a Web Forms
or another type of application instead, skip to step 21 or later. Right-click the new Frontend folder and choose
Add | New Project. In the tree on the left, click the Web category and then choose ASP.NET MVC 4 Web
Application.
17.
As the name of the project, enter Spaanjaars.ContactManager45.Web.Mvc.18.
As the location for the project enter C:\Projects\Spaanjaars.ContactManager45\Main\Applications.19.
Click OK to add the project.20.
In the New ASP.NET MVC 4 Project dialog, choose Internet as the template. Make sure Razor is selected as the
View Engine and if necessary, clear the checkbox for creating a unit test project. The unit test projects are
added separately to the solution in the next article.
21.
Repeat steps 17 through 20, but this time add a new ASP.NET Web Forms Application and name it
Spaanjaars.ContactManager45.Web.WebForms.
22.
Repeat steps 17 through 20 again, but this time add a new WCF Service Application and name it
Spaanjaars.ContactManager45.Web.Wcf.
23.
Repeat steps 17 through 20 again, but this time add a new Console Application from the Windows category
and name it Spaanjaars.ContactManager45.Import.
24.
Tip: if you forget to store one of the projects in the Applications folder, remove the project from the Solution
Explorer (right-click the project and choose Remove). Move the project to the Applications folder using File Explorer
and then add the project to the solution again using its Add Existing Project option.
Your Solution Explorer should now look similar to Figure 2-525.
Figure 2-5 The Solution Explorer with all Application Projects
From the Model project, add a reference to the Infrastructure project. Next, from the Repositories.EF
project, add a reference to the Infrastructure and Model projects. Finally, from each of the four frontend
projects add a reference to the Infrastructure, Model and Repositories.EF projects.
26.
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 21 of 162
Next, right-click the Solution and choose Rebuild Solution. This compiles the application and makes sure that
everything is ready for the next steps.
27.
Optimizing the SolutionHere are a few tips to get the Visual Studio solution in a good shape:
Use NuGet to update all packages that were added by Visual Studio when you created the new projects.
Libraries like jQuery, jQuery UI and Entity Framework are updated regularly, and are likely to be outdated
when you added them to the solution. To update the packages, right-click the solution and choose Manage
NuGet Packages for Solution. Next, click Updates on the left and then update each individual package that has
updates.
1.
Consider enabling NuGet Package Restore. With this feature enabled, Visual Studio downloads missing
packages whenever you build your solution. This is useful if you work in a team and use a shared code
repository such as TFS, because packages added by one member are downloaded automatically the next time
another team member builds the solution. To enable this feature, right-click the Solution and choose Enable
NuGet Package Restore. You also need this option to build the sample application that comes with this article.
See the Readme.txt file in the download for more details.
2.
Delete unneeded .cs files and other boilerplate stuff you dont need. For example, if you havent already done
so, remove the Class1.cs files from the class library projects. In addition, remove the IService1.cs,
Service1.svc and Service1.svc.cs files from the WCF project.
3.
Adding your Solution to TFSNow that the skeleton for the solution is ready, its a good time to add it to your source control system. If you dont
use such a system, you can skip this section (although you should seriously consider using one; you can get a free
hosted TFS solution for up to five team members at http://tfs.visualstudio.com/). The following section uses TFS as
the source control system, but similar concepts apply to other source control systems.
Using Team Explorer, connect to your TFS Server.1.
On the Solution Explorer, right-click the Solution and choose Add Solution to Source Control.2.
Click the appropriate TFS Project.3.
As the name for the solution folder, enter Spaanjaars.ContactManager45/Main. The /Main part is not a typo.
In fact it's very important as itll create an additional folder in TFS which you can set up as main branch later.
4.
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 22 of 162
Figure 2-6 The Add Solution to Source Control Dialog
Click OK.5.
Your Source Control Explorer (accessible from the Team Explorer) should now look like this:6.
(8) See Links in this Document at the end for the full URL of this image.
Figure 2-7 The Source Control Explorer
Right-click the Main folder in the Source Control Explorer and choose Check In.7.
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 23 of 162
As a comment, enter something like Initial Commit and click Check In.8.
Still in the Source Control Explorer, right-click the Main folder and choose Branching and Merging | Convert to
Branch.
9.
Enter a description such as Main Branch and click Convert.10.
Thats it. From now on, other developers can get a local copy of this solution simply by opening the .sln file
from the Main folder. When they compile the application, Visual Studio will automatically attempt to download
the missing packages (provided you enabled NuGet Package Restore as explained earlier) removing the need
to store these packages in TFS.
11.
For more information about creating a branch, check out the original article on adding solutions to TFS
(http://imar.spaanjaars.com/565/recommendations-for-setting-up-a-visual-studio-solution-for-tfs). In addition, check
out the Branching and Merging guide at http://vsarbranchingguide.codeplex.com/.
Stuff I Like to DoHere are a few tips to keep your solution in great shape, and easy to manage:
Scan the list of installed packages for each project and remove the ones you dont need. Adding them back in
later is easy to do.
1.
From time to time, scan the Updates for the installed packages. Then for each package, consider whether you
want to upgrade or not. Some updates cause breaking changes or require you to change code first.
2.
I like to keep a document in my Solution called Readme.txt or Stuff I Learned.txt where I keep a list of
interesting blog posts, references to open source projects, sample implementations and more. To add this file,
follow these steps:
In the folder where the .sln file resides on disk (at C:\Projects\Spaanjaars.ContactManager45
\Main) create a new folder called Documentation.
1.
Inside this new folder create a new text file called Readme.txt.2.
Switch to Visual Studio, right-click the Solution and choose Add | New Solution Folder. Name the
folder Documentation.
3.
Right-click this new folder and choose Add | Existing Item. Browse for the Readme.txt file in the
Documentation folder and click Add to add the file to the solution.
4.
If youre using TFS or another source control system, right-click the solution in the Solution Explorer
and choose Check in. This enables you to store the solution files and folders in TFS as well.
5.
3.
SummaryIn this article, you saw how to set up a Visual Studio solution and a number of projects. By following the
recommendations from this article with regards to project naming and their location on disk your solution will be easy
to manage for you and anybody else in your team that may need to have access to it. By storing all your projects in
folders below the .sln file, opening the application from source control is as easy as double-clicking the .sln file in
the Source Control Explorer.
In the next article (9)
youll see how to add various flavors of unit test projects to the solution. If youre not interested
in unit testing (yet), you can skip directly to Part 4 (10)
. However, I still encourage you to read Part 3 as it might
change your mind on whether unit testing is something for you or not.
Links in this Document(1) http://imar.spaanjaars.com/573/building-n-layered-applications-with-aspnet-45-part-1-introduction
(2) http://imar.spaanjaars.com/575/building-n-layered-applications-with-aspnet-45-part-3-making-your-projects-
unit-testable
(3) http://imar.spaanjaars.com/565/recommendations-for-setting-up-a-visual-studio-solution-for-tfs
(4) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part02/Figure2-01_The_New_Project_Dialog.png
(5) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part02
/Figure2-02_Windows_Explorer_Showing_the_Solution.png
(6) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part02
/Figure2-03_Add_New_Project_for_Model.png
(7) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part02
/Figure2-04_Windowes_Explorer_Model_Project.png
(8) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part02
/Figure2-07_The_Source_Control_Explorer.png
(9) http://imar.spaanjaars.com/575/building-n-layered-applications-with-aspnet-45-part-3-making-your-projects-
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 24 of 162
unit-testable
(10) http://imar.spaanjaars.com/576/building-n-layered-applications-with-aspnet-45-part-4-implementing-a-model
ASP.NET N-Layered Applications - Setting up the Solution in Visual Studio (Part 2)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 25 of 162
ASP.NET N-Layered Applications - Making your Projects Unit
Testable (Part 3)This is Part 3 in a series of 10 that show you how to build N-Layered applications using ASP.NET 4.5 and Entity
Framework 5 Code First. In this part youll see how to make your solution unit testable. In addition, youll see how to
setup a project for Integration tests which work similar to unit tests but that target the database directly.
Note: as mentioned in Part 1, this article (and the previous) will contain a lot of hands-on, step by step instructions
that show you how to setup a solution like the Spaanjaars.ContactManager application. You can use these instructions
pretty much as-is for your own applications. The remaining parts in the series analyze the working code for the
Spaanjaars.ContactManager application. Ill show a lot of the code in detail, and explain how it works, but you wont
find detailed step by step instructions on how to add the code and files to the various projects.
Making Your Projects Unit TestableTo ensure a better quality of your software, its highly recommended to add unit tests to your projects. This way, you
can test your code during development, minimizing the chance of introducing issues and finding and fixing them before
they ever make it into production code. This article does not explain the need for unit testing in detail nor does it
explain how to write good unit tests. For a good introduction into unit testing, check out the following references:
The Art of Unit Testing (Roy Osherove, Manning Publications, 2009: http://www.amazon.com/Art-Unit-Testing-
Examples-Net/dp/1933988274)
http://msdn.microsoft.com/en-us/library/bb385902%28v=vs.90%29.aspx
http://msdn.microsoft.com/en-us/library/hh694602.aspx
http://geekswithblogs.net/thomasweller/archive/2011/02/21/an-introductory-presentation-about-testing-
with-mstest-visual-studio-and.aspx
This article does, however, show you how to differentiate your types of tests (using different Test Projects in Visual
Studio) and how to configure the solution so that the test projects can see the relevant assemblies in the solution. In
many previous solutions I built, I use more than one test project, described in the following table:
Type Suggested name suffix Description
Unit Tests.Unit This project contains all the unit tests that dont have a
dependency on a database or the UI. In the sample application,
it contains tests for model entity properties, model validation,
and more.
For applications with a larger model you could further separate
the unit tests into separate Visual Studio projects, each named
after the area of the application they are targeting.
Integration Tests.Integration This test project contains integration tests that have
dependencies to other components of the system, such as a
database. In the sample project you find tests that use the
Repositories.EF project to interact with a SQL Server database
directly.
For applications with a larger model you could further separate
the integration tests into separate Visual Studio projects, each
named after the area of the application they are targeting.
Frontend Tests.Frontend.Mvc This test project contains tests that target the presentation layer.
It could contain Coded UI tests and tests targeting the ASP.NET
MVC controller framework. In the sample application you only
find unit tests for MVC controllers but you could easily add more
tests to this project.
Frontend Tests.Frontend.Wcf This test project contains tests for the various service methods
inside the WCF service project.
In the next steps youll see how to add these four Test Projects to the solution. I am showing you how to add all four;
one for each frontend application added to the solution in the previous article. If, however, your solution has fewer
frontend implementations, only add the test projects for your particular frontend(s).
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 26 of 162
In order to better organize my solution, I prefer to group all my test projects in a Solution Folder called Tests. This is
not required, but it makes it easier to get access to all your test projects at once, or hide them when youre working
on the actual code for the project.
To add a Solution Folder for the tests, right-click the Solution in the Solution Explorer and choose Add | New
Solution Folder. Name the folder Tests.
1.
Right-click this new Tests folder and choose Add | New Project. Select your preferred programming language
and then, from the Test category, select Unit Test Project. Name the project
Spaanjaars.ContactManager45.Tests.Unit and change the Location for the project to C:\Projects
\Spaanjaars.ContactManager45\Main\Tests. By storing your test projects in the Tests folder you separate
them from the actual implementation projects that are stored in the Applications folder. In the Target
Framework drop-down list make sure .NET Framework 4.5 is selected.
This project is going to contain the core unit tests for the Contact Manager application.
2.
(1) See Links in this Document at the end for the full URL of this image.
Figure 3-1 The Add New Project Dialog
Click OK to add the project to the solution.3.
Add another Unit Test Project to the Tests Solution Folder, name it
Spaanjaars.ContactManager45.Tests.Integration and make sure its saved in the folder C:\Projects
\Spaanjaars.ContactManager45\Main\Tests as well. This project will contain tests that are going to access
the database directly.
4.
Add another Unit Test Project to the Tests Solution Folder, name it
Spaanjaars.ContactManager45.Tests.Frontend.Mvc and make sure its saved in the folder C:\Projects
\Spaanjaars.ContactManager45\Main\Tests. This project will contain tests that target the ASP.NET MVC 4
project.
5.
Add another Unit Test Project to the Tests Solution Folder, name it
Spaanjaars.ContactManager45.Tests.Frontend.Wcf and make sure its saved in the folder C:\Projects
\Spaanjaars.ContactManager45\Main\Tests. This project will contain tests that target the WCF service
project.
6.
In these four new test projects, add references to the following projects in your solution:7.
Project References
Tests.UnitSpaanjaars.ContactManager45.Infrastructure
Spaanjaars.ContactManager45.Model
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 27 of 162
Tests.IntegrationSpaanjaars.ContactManager45.Infrastructure
Spaanjaars.ContactManager45.Model
Spaanjaars.ContactManager45.Respositories.EF
Tests.Frontend.MvcSpaanjaars.ContactManager45.Infrastructure
Spaanjaars.ContactManager45.Model
Spaanjaars.ContactManager45.Web.Mvc
System.Web.Mvc (found in %programfiles(x86)%\Microsoft
ASP.NET\ASP.NET MVC 4\Assemblies by default)
Tests.Frontend.WcfSpaanjaars.ContactManager45.Infrastructure
Spaanjaars.ContactManager45.Model
Spaanjaars.ContactManager45.Web.Wcf
Your Solution Explorer should now look like this:
Figure 3-2 The Solution Explorer with the new Unit Test Projects
On disk your Solution should look like this in File Explorer:
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 28 of 162
(2) See Links in this Document at the end for the full URL of this image.
Figure 3-3 File Explorer Showing the new Unit Test Projects
Finalize the configuration of your projects. For example, you can delete the existing default Unit Test files
(called UnitTest1.cs inside each project). You can also add additional packages such as FluentAssertions (3)
(for which youll find instructions later in this article) or references to external libraries.
6.
Finally, do a full rebuild of the entire solution to ensure everything is set up correctly and resolve any
compilation errors you may have.
7.
In the next section youll see how to add a simple test to three of the four Unit Test projects in order to ensure your
projects, including the Infrastructure, Model and Repositories.EF projects as well as the Unit Test projects itself,
have been set up correctly. In order for this to work, Ill also add a few classes to the core projects with some
temporary implementation. That code will be expanded or replaced in later articles.
In the Model project, add a new public class called Person and give it an automatically implemented property
of type int called Id. You should end up with code like this:
8.
In the project Spaanjaars.ContactManager45.Tests.Unit add a new Unit Test file called PersonTests.cs
and modify the code as follows.
9.
1234567
namespace Spaanjaars.ContactManager45.Model{ public class Person { public int Id { get; set; } }}
123456789
1011121314
using Microsoft.VisualStudio.TestTools.UnitTesting;using Spaanjaars.ContactManager45.Model; namespace Spaanjaars.ContactManager45.Tests.Unit{ [TestClass] public class PersonTests { [TestMethod] public void NewPersonHasEmptyId() { var person = new Person(); Assert.AreEqual(0, person.Id); }
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 29 of 162
Run all the tests (theres only one at the moment) in the solution by pressing Ctrl+R, followed by an A
(Ctrl+R, A) or by choosing Tests | Run | All Tests from the main menu. Then check the Test Explorer (which
you can open using Test | Windows | Test Explorer). You should see that the test has passed:
Figure 3-4 Test Explorer Showing Success
Note: You would normally write a test that fails first, to avoid ending up with false positives. You would then
implement some code to make the test pass. In this case, the test is so simple (and not really meant to test
the functionality of the Person class, but rather the setup of the test project itself) that I decided to write a
"green test" directly.
10.
Next, add a new public class called PeopleRepository.cs to the
Spaanjaars.ContactManager45.Repositories.EF project. Dont forget to add public in front of the class or
itll default to internal. Theres no need to add any code to the class for now.
11.
In the project Spaanjaars.ContactManager45.Tests.Integration, add a new Unit Test file, call it
PeopleRepositoryTests.cs and modify the code as follows:
12.
Note: this is a pretty useless test. You should have other tests that implicitly check whether you can instantiate a new
PeopleRepository class and then work with that instance. However, for now this test is useful to make sure that the
Integration project has the correct references to the Repositories.EF project.
Press Ctrl+R, A again. Both tests should pass.13.
In the test project Spaanjaars.ContactManager45.Tests.Frontend.Mvc add a new Unit Test file called
HomeControllerTests.cs and modify its code as follows:
14.
1516
}}
123456789
10111213141516
using Microsoft.VisualStudio.TestTools.UnitTesting;using Spaanjaars.ContactManager45.Repositories.EF; namespace Spaanjaars.ContactManager45.Tests.Integration{ [TestClass] public class PeopleRepositoryTests { [TestMethod] public void CanInstantiatePeopleRepository() { var peopleRepository = new PeopleRepository(); Assert.IsNotNull(peopleRepository); } }}
123456789
10
using System.Web.Mvc;using Microsoft.VisualStudio.TestTools.UnitTesting;using Spaanjaars.ContactManager45.Web.Mvc.Controllers; namespace Spaanjaars.ContactManager45.Tests.Frontend.Mvc{ [TestClass] public class HomeControllerTests { [TestMethod]
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 30 of 162
Press Ctrl+R, A once more. All three tests should now pass, as shown in Figure 3-5:15.
Figure 3-5 Test Explorer Showing Green Tests
For now, these tests are really simple and only serve to verify the setup and relationships between the various
projects. I skipped the tests for the WCF service as the current project doesnt have any code files and adding a WCF
service requires more background which Ill cover in Part 8 (4)
of this series.
Ill be adding more tests to the test projects as I progress through this article series. I wont show you the code for all
of the tests though; Ill only highlight some of the more important ones. Youre encouraged to check out the source
code that comes with this article series to see all the tests.
Using Fluent AssertionsThere are a number of open source frameworks available that make unit tests easier to read and more obvious. One of
those frameworks is FluentAssertions (5)
created by Dennis Doomen (6)
. This framework allows you write the
assertions for your test in a fluent way. E.g. rather than writing something like this:
You can now write something like this:
Although you may need to get used to this new syntax at first, I generally find it more intuitive to read. Its very useful
to quickly see what your tests do but more importantly, non-technical people involved in a project can now more or
less read unit tests too. This enables them to help you write the proper tests.
Under the hood, the various FluentAssertions methods check your values and raise exceptions when a condition is not
met. This exception is eventually caught by MS test or another test framework you may be using.
In order to change your test projects to use FluentAssertions, follow these steps:
Inside Visual Studio, open up the Package Manager Console by choosing Tools | Library Package Manager |
Package Manager Console.
1.
Select your Integration test project from the Default project drop-down (called
Spaanjaars.ContactManager45.Tests.Integration if youre following along with the walkthroughs in this
article series).
2.
In the Package Manager Console type Install-Package FluentAssertions and hit enter.3.
Repeat step 2 and 3, three more times, but now add FluentAssertions to the Unit tests project, the4.
1112131415161718
public void IndexHasNoModel() { var controller = new HomeController(); var result = controller.Index() as ViewResult; Assert.AreEqual(null, result.Model); } }}
1 Assert.AreEqual(3, id);
1 id.Should().Be(3);
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 31 of 162
Frontend.Mvc project and the Frontend.Wcf project.
Open up the PersonTests class in the Unit Tests project and at the top of the file add the following using
statement:
5.
Change the last line of the NewPersonHasEmptyId test to the following:
With this change, the code almost reads like English; the ID of the new person created in code should be zero.
6.
Next, run your test(s) to see if everything still works. If they pass (and they should), you should see a nice
green checkmark in the Unit Test Explorer:
7.
Figure 3-6 Test Explorer Showing Green Tests
You can find out more about FluentAssertions on the projects site at CodePlex.com:
http://fluentassertions.codeplex.com/.
Stuff I Like to DoHeres a quick list of things I like to do when it comes to unit testing:
Use FluentAssertions, as just explained. Its one of the first things I add to a Visual Studio test project.
Write a base class for all your tests and let your test classes inherit from it. Even if you dont add any behavior
yet, its useful to have all your test classes inherit a common base class to which you can add shared
functionality as you go. In the code download youll find a base class in each of the four test projects. In the
Integration tests project the base class is used to initialize the database (generated by EF) for each set of tests.
Youll see more of this in Part 5 when the database initializer is discussed.
Set up an automated build in TFS to run all your tests whenever code is checked in. This is a great way to
ensure your code is always in a valid state. For more details, see:
Professional Team Foundation Server 2012 (Ed Blankenship et al., Wrox, 2013, http://www.wrox.com
/WileyCDA/WroxTitle/Professional-Team-Foundation-Server-2012.productCd-1118314093.html)
http://msdn.microsoft.com/en-us/library/ms181716.aspx
Consider getting a Unit Test runner such as the ones supplied by ReSharper or CodeRush. Although the test
runner in Visual Studio 2012 has improved somewhat since Visual Studio 2010, I find the third party runners
easier and more powerful to work with. More details can be found here:
Unit Testing with CodeRush (http://www.devexpress.com/Products/Visual_Studio_Add-
in/Coding_Assistance/unit_test_runner.xml)
Unit Testing with ReSharper (http://www.jetbrains.com/resharper/webhelp/Unit_Testing__Index.html)
SummaryIn this article you saw how to add a number of different unit test projects to your solution and how to set them up.
While you could technically add all your tests to a single unit test project, I prefer to create separate projects for
different types of tests. This allows me to decide when to run which tests. For example, because Integration tests
generally run slower than plain unit tests (because they access databases and other slow resources), I could decide to
run my unit tests after each build while the integration tests are only run when I check in code into TFS.
1 using FluentAssertions;
1 person.Id.Should().Be(0);
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 32 of 162
At this point, each test project contains a simple unit test that is used purely to check if the test projects were setup
correctly. In later parts in this article series youll see how to add more useful tests to the different test projects.
With all the plumbing done, the next step is to start building the model. In the next part in this article series youll
see how to set up the model using POCO Plain Old CLR Objects - classes. That model is then used in Part 5 that
describes how to build a repository that targets Entity Framework 5 Code First to interact with the database. In the
articles following Part 5 Ill show you how to use the model and the repositories to build various frontend applications.
Links in this Document(1) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part03/Figure3-01_Add_New_Test_Project.png
(2) Image: http://imar.spaanjaars.com/Images/Articles/NLayer45/Part03
/Figure3-03_Windows_Explorer_With_Test_Projects.png
(3) http://fluentassertions.codeplex.com/
(4) http://imar.spaanjaars.com/580/building-n-layered-applications-with-aspnet-45-part-8-putting-it-all-together-
implementing-a-wcf-45-frontend
(5) http://fluentassertions.codeplex.com/
(6) http://www.dennisdoomen.net/
ASP.NET N-Layered Applications - Making your Projects Unit Testable (Part 3)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 33 of 162
ASP.NET N-Layered Applications - Implementing a Model (Part
4)This is Part 4 in a series of 10 that show you how to build N-Layered applications using ASP.NET 4.5 and Entity
Framework 5 Code First. In this part youll see how to build a model using POCO classes Plain Old CLR Objects that
have no dependencies to external frameworks (such as a requirement to inherit from an Entity Framework base class).
In addition, you will see how to create unit tests for your POCO classes as well as lay a foundation for validation of
these classes.
IntroductionIn Part 1 of this article series you saw a brief overview of the functionality of the ContactManager application version
4.5. Most of the functionality is very similar to the design presented in the 2.0 and 3.5 versions of my N-Layered
architecture articles.
Because the functionality is so similar, Ill skip the requirements gathering phase. Normally, when you start a new
project you dont know up front how your application and model should look. To figure out the type of application, the
underlying model and the functionality, you typically have workshops with your client to gather all the requirements.
These requirements then drive the design of the application and the model, which is a representation of the objects in
your domain that your application is going to work with. In the 2.0 version of this series (1)
I wrote about the
requirements for the ContactManager application. Youre encouraged to check out the Design - Gathering
Requirements section in the original article to find out more about the model for that application. In the new series,
the model I use is pretty similar, as youll see in the following sections.
To learn more about how to gather requirements to design your applications and models, check out the following
publications:
http://imar.spaanjaars.com/416/building-layered-web-applications-with-microsoft-aspnet-20-part-
1#gatheringrequirements
Practicing Domain-Driven Design (Scott Millett, under development: https://leanpub.com/Practicing-DDD)
Implementing Domain-driven Design (Vaughn Vernon, 2013, http://www.amazon.com/Implementing-Domain-
Driven-Design-Vaughn-Vernon/dp/0321834577/)
Based on the model from the previous article series, the application needs the following classes:
Class Name Description
Person This class represents a contact person used to keep track of your contacts.
Address This class represents a physical address that can be associated with a person.
EmailAddress This class represents an e-mail address of a person.
PhoneNumber This class represents a phone number of a person.
In addition to these classes, the model also needs the following types:
Type Name Type Description
PersonType Enum Defines the type of a person, such as Friend, Family or Colleague.
ContactType Enum Defines the type of the e-mail addresses and phone numbers, such as
Business or Personal.
People
EmailAddresses
PhoneNumbers
Class These classes are created to hold a collection of each of the main
entities in the model. While you could use more generic collections such
as List, I prefer to create separate collections for each main type.
You will see how to create these collections later.
The following diagram shows all of these types. Later sections of this article describe the various types in more detail,
including their underlying code and place in the application.
ASP.NET N-Layered Applications - Implementing a Model (Part 4)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 34 of 162
(2) See Links in this Document at the end for the full URL of this image.
Figure 4-1 The Class Diagram for the Model project
If you look carefully at the list of types in the diagram, youll notice the collection class for Address is missing. The
reason for this is that the current application doesnt need it. The person class has two properties of type address
ASP.NET N-Layered Applications - Implementing a Model (Part 4)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 35 of 162
called HomeAddress and WorkAddress respectively. This is a change from the original design where a contact person
could have a collection of addresses as well. Ive done this to show you the concept of Value Objects which are
discussed next. Entity Framework (EF) doesnt work well with collections of Value Objects and thus I decided to add
the Address class as singular properties directly on the Person class.
Where Does the Model Fit In?The classes defined in the Model layer flow between the concrete repositories and the user interface. The UI should
preferably not know anything, or at least as little as possible about the concrete repositories and should work with the
repository interfaces instead. If you think back about the architecture diagram from Part 1, the Model classes would be
placed between the concrete repositories and the associated interfaces and between the repository interfaces and the
UI. Figure 4-2 shows the updated diagram:
ASP.NET N-Layered Applications - Implementing a Model (Part 4)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 36 of 162
(3) See Links in this Document at the end for the full URL of this image.
Figure 4-2 Model Classes in the Architecture Diagram
Defining Your Types
ASP.NET N-Layered Applications - Implementing a Model (Part 4)
Imar Spaanjaars - http://imar.spaanjaars.com - 2013 Page 37 of 162
Once youve identified the core types for your application, the next step is to place them in one of two groups: Entities
or Value Objects, two terms that come from the Domain Driven Design language. A lot has been written about the
differences between the two (see the links at the end of this section), so I wont repeat the complete discussion here.
Instead, Ill summarize the differences and explain what the differences mean for the ContactManager application.
An Entity is an object that is identified by a unique ID, rather than by the value it represents. The canonical example is
the Person class. If two Person instances have the same name, do you consider them to represent the same person?
Most likely not, as the name would not uniquely identify the person, and theres a high probability that even though
these instances contain the same name they refer to two different people in the real world.
A Value Object on the other hand is identified by its properties and the values they contain. The canonical example
here is Address: two instances of Address that contain the data 327 Washington Blvd Venice, California 90291 are
most likely considered the same; they dont have (or need) an identity on their own.
You can read more about the differences between Entities and Value Objects in the following articles:
http://stackoverflow.com/questions/75446/value-vs-entity-objects-domain-driven-design
http://lostechies.com/jimmybogard/2008/05/21/entities-value-objects-aggregates-and-roots/
http://devlicio.us/blogs/casey/archive/2009/02/13/ddd-entities-and-value-objects.aspx
To make the distinction in your code between these two types, its a good idea to create two base classes that your
entities can inherit from. You see how to do this next.
Creating the InfrastructureIn this section you see how to implement the Infrastructure project by creating two base classes: one for an Entity
and one for a Value Object.
Note: Ill show the implementation of a number of types step by step. That means that the code you see may not be
the final code in the project.
Creating Base Classes for Entities and Value Types
A base class for an Entity requires at least an identity property which is typically called Id, although, youre free to
make up another name. Since the base class should be reusable across multiple type definitions, its a good idea to
make the type of this Id column generic so that classes that inherit this base class can determine the actual type (for
example, an int or a Guid). The class could also have an IsTransient method that determines if the object is new
(has not been assigned an ID by the underlying database) or not. To implement this base class, I added a new class
file to the Spaanjaars.Infrastructure project, called it DomainEntity.cs and added the following code:
Heres the class diagram f