164
Building N- Layered Applications with ASP.NET 4.5 © 2013 - Imar Spaanjaars – http://imar.spaanjaars.com

Building N-Layered Applications with ASP.NET 4.5.pdf

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