Lesson 64 - Using a Maintenance-Driven Approach to Building a Database Application

Tutorial Series: Free C# Fundamentals via ASP.NET Web Apps

Previous Article  |  Next Article

Get GitHub Code

In the previous lesson, we saw the benefits of using a Tools Driven development approach, which is a great approach if you are looking at a departmentally scoped application that you need to create quickly. This approach requires very little logic, and is feasible for simple “CRUD” style database operations (create, read, update, delete), where you don't really anticipate any changes in the long term. However, not every application is like that. Many applications are not scoped to that of a small department, but rather at an Enterprise level. In that case, a fast turn-around is far less important than getting it right and having it flexible enough to anticipate inevitable changes in the system.


We’re looking at two different extremes to solving development problems. In reality, there are gradations – in between the completely Tools Driven and completely Maintenance Driven approaches – that utilize a bit of both in order to get the job done.

Step 1: Backtrack to Lesson 61

For this lesson, we will start with where we left off in Lesson 61 – backtracking away from what we learned about the Tools Driven approach, and re-assessing the problem through the lens of a Maintenance Driven approach instead. A Maintenance Driven approach should start with a logical separation of concerns between the three main layers. Start by renaming the project to “LocalDbExample.Presentation”:


Step 2: Add New Project Layers

Next, let’s add the two other layers by selecting from Visual Studio’s menu:

File > Add > New Project

In the New Project Dialogue, navigate to a Class Library, and make sure to change the selection for Solution to 'Add to Solution' not 'Create New Solution'. Name the file LocalDbExample.Domain:


Repeat these steps to create a LocalDbExample.Persistence layer as well. Afterwards, rename the Class1.cs files in these layers as follows:


At this point, it’s probably a good idea to build the Solution to make sure everything is set up correctly. The shortcut key for building a solution is:


Step 3: Set Dependencies between Project Layers

Building is important so that each project can “see” the other’s and allow dependencies to be established. When one project takes a dependency from another one, it simply means it makes reference to it in code. Ideally, you will want to keep your code as independent as possible but a certain amount of dependency is going to be necessary. Set up a Domain dependency on the Persistence layer by right-clicking on “References” and selecting “Add Reference…”:


From here, select the Persistence layer as a dependency and after that, you should see it in your list of References under LocalDbExample.Domain:


Repeat this process, adding a dependency to the Domain layer in the Presentation layer’s References. Of course it would be better to have the Presentation, and Persistence layers depend on the Domain layer, which at least keeps the dependency chain central to the Domain layer. However, for now, we are going to simplify things and have the Presentation layer depend on the Domain layer, and the Domain Layer depend on the Persistence layer, represented in red arrows below:


Now we will have to re-create the Entity model in the Persistence layer. In the Solution Explorer, right-click on the LocalDbExample.Persistence layer and add a new item. From the available templates, select the ADO.NET Entity Data Model as we did in the previous lesson:


On the next screen choose “EF Designer from database”:


Next, we’re going to save the database connection settings to an App.config file (typically, you would not want to use an App.config but rather a Web.config for an actual web application. However, it will work for the purposes of this demonstration):


The next step asks if you would like to copy the file to the project, select “No” to this step:


At the next step select Entity Framework 6.x, and then click “Next”:


The setup wizard will then ask you which database object you would like to include in your model. Select all of the Tables, and then click “Finish”:


After that you will end up with an Entity model in the Persistence layer, complete with a Customer class it automatically created to model the database table of the same name:



Go now to the CustomerRepository.cs class and write a method that returns a List<Customer> obtained from the database via the Entities model:


Now in the Domain layer's CustomerManager.cs class, we will need to reference the Persistence layer through a using statement added to the top of the script:


And then in the CustomerManager class, write a method that simply calls Persistence.CustomerRepository.GetCustomers() and returns the List<Customer>:


At this point, we’ve exposed the Entity Framework Persistence layer to the Domain layer via this reference in the CustomerManager class. Exposing these inner workings is not a great idea, because we lose the clear separation of concerns that makes this approach valuable. What we need to do is add one more project called a Data Transfer Object Layer (DTO). The purpose of this layer is to abstract away the three main layers from each other, as they really should not have to know about one another to do their individual job. The DTO layer acts as the common reference point instead, and its dependency relationship to the other layers can be viewed as follows:


Let’s now add this DTO layer to our project – using the steps outlined previously in the lesson – calling it “LocalDbExample.DTO.” We will want to copy and paste the exact same class structure for the Customer class in the Persistence layer , and place it in the Class1.cs file (rename this file to Customer.cs as well):



Now we will want to add a reference to LocalDbExample.DTO under each other project’s “References” in the Solution Explorer (remember, each project should point to this one, rather than to one another).

LocalDbExample.Domain Reference:


LocalDbExample.Persistence Reference:


LocalDbExample.Presentation Reference:


The Persistence Layer's CustomerRepository class currently references the Presentation layer's Customer in the GetCustomers() method. What we should do instead at this point is reference the DTO.Customer class, instead of storing the pulled databased data to a local Customer Class reference. To do this, modify CustomerRepository as follows:

  1. Retain the code that pulls database data and stores it to a List<Customer> object.

  2. Create a new, locally scoped List<DTO.Customer> object.

  3. In a foreach() create a temporary DTO.Customer object.

  4. Populate each property for this object using the properties from the iterated List<Customer>

  5. Add the DTO.Customer to the List<DTO.Customer>.

  6. Return the List<DTO.Customer>, making sure to also change the return type in the method signature.


The Domain Layer is what calls GetCustomers(), but if you look at the method that initiates the call, you'll see that we're currently returning the wrong type, Persistence.Customer. Change the return type to a List<DTO.Customer> because the CustomerRepository will be returning that data to the caller.


Turning our attention now to the Presentation layer, first delete the ACMEEntities.edmx as we will be using the database from the Persistence layer instead:


Now change the Page_Load() method, within Default.aspx.cs, to reflect the reference to the Domain layer:


The last thing to do is set the Presentation layer as the entry-point for the application by right-clicking it and selecting from the menu “Set as Startup Project”:


Now, when you run the application you will see the same results as the previous lesson but with a cleaner, more separated application structure behind the scenes:


If you received an error upon running the application, there might be a mismatch between the connectionString stored in the App.config and Web.config files, respectively. You will find the connectionString in each file, represented here in App.config as “…” (your actual connection string will be a much longer):


To fix the error, simply (1) copy the entire connectionString from App.config in the Persistence layer and (2) paste it over the connectionString in Web.config in the Presentation layer.



You might be thinking that this is a lot of effort just to build a simple application. Especially because we already saw that it could be made more easily with a tools driven approach. While this methodology won't make a lot of sense for a simple application, keep in mind that applications are not typically this small. They are often very large, or in the case of Enterprise level applications, absolutely massive in scope. Think of the time spent setting up the code and keeping layers separate as an investment. Over time, when changes need to be made to your application, the time spent in this step will be well worth your while, because you won't need to completely rebuild your application from the ground up.

Related Articles in this Tutorial:

Lesson 1 - Series Introduction

Lesson 2 - Installing Visual Studio 2015

Lesson 3 - Building Your First Web App

Lesson 4 - Understanding What You Just Did

Lesson 5 - Working with Projects in Visual Studio

Lesson 6 - Simple Web Page Formatting in Visual Studio

Challenge 1

Solution 1

Lesson 7 - Variables and Data Types

Lesson 8 - Data Type Conversion

Lesson 9 - Arithmetic Operators

Lesson 10 - C# Syntax Basics

Challenge 2 - ChallengeSimpleCalculator

Solution - ChallengeSimpleCalculator

Lesson 11 - Conditional If Statements

Lesson 12 - The Conditional Ternary Operator

Challenge 3 - ChallengeConditionalRadioButton

Solution - Challenge Conditional RadioButton

Lesson 13 - Comparison and Logical Operators

Lesson 13 Challenge - First Papa Bob's Website

Solution - Challenge First Papa Bob's Website

Lesson 14 - Working with Dates and Times

Lesson 15 - Working With Spans of Time

Lesson 16 - Working with the Calendar Server Control

Challenge 4 - Challenge Days Between Dates

Solution - Challenge Days Between Dates

Lesson 17 - Page_Load and Page.IsPostBack

Lesson 18 - Setting a Break Point and Debugging

Lesson 19 - Formatting Strings

Challenge 5 - Challenge Epic Spies Assignment

Solution - Challenge Epic Spies Assignment

Lesson 20 - Maintaining State with ViewState

Lesson 21 - Storing Values in Arrays

Lesson 22 - Understanding Multidimensional Arrays

Lesson 23 - Changing the Length of an Array

Challenge 6 - Challenge Epic Spies Asset Tracker

Solution - Challenge Epic Spies Asset Tracker

Lesson 24 - Understanding Variable Scope

Lesson 25 - Code Blocks and Nested If Statements

Lesson 26 - Looping with the For Iteration Statement

Challenge 7 - Challenge For Xmen Battle Count

Solution - Challenge For Xmen Battle Count

Lesson 27 - Looping with the while() & do...while() Iteration Statements

Lesson 28 - Creating and Calling Simple Helper Methods

Lesson 29 - Creating Methods with Input Parameters

Lesson 30 - Returning Values from Methods

Lesson 31 - Creating Overloaded Methods

Lesson 32 - Creating Optional Parameters

Lesson 33 - Creating Names Parameters

Lesson 34 - Creating Methods with Output Parameters

Challenge 8 - Challenge Postal Calculator Helper Methods

Solution - Challenge Postal Calculator Helper Methods

Mega Challenge Casino

Solution - Mega Challenge Casino

Lesson 35 - Manipulating Strings

Challenge 9 - Phun With Strings

Solution - Challenge Phun With Strings

Lesson 36 - Introduction to Classes and Objects

Challenge - Hero Monster Classes Part 1

Solution - Hero Monster Classes Part 1

Challenge - Hero Monster Classes Part 2

Solution - Challenge Hero Monster Classes Part 2

Lesson 37 - Creating Class Files Creating Cohesive Classes and Code Navigation

Lesson 38 - Understanding Object References and Object Lifetime

Lesson 39 - Understanding the .NET Framework and Compilation

Lesson 40 - Namespaces and Using Directives

Lesson 41 - Creating Class Libraries and Adding References to Assemblies

Lesson 42 - Accessibility Modifiers, Fields and Properties

Lesson 43 - Creating Constructor Methods

Lesson 44 - Naming Conventions for Identifiers

Lesson 45 - Static vs Instance Members

Challenge 10 - Challenge Simple Darts

Solution - Challenge Simple Darts

Lesson 46 - Working with the List Collection

Lesson 47 - Object Initializers

Lesson 48 - Collection Initializers

Lesson 49 - Working with the Dictionary Collection

Lesson 50 - Looping with the foreach Iteration Statement

Lesson 51 - Implicitly-Typed Variables with the var Keyword

Challenge 11 - Challenge Student Courses

Solution - Challenge Student Courses

Mega Challenge War

Solution - Mega Challenge War

Lesson 52 - Creating GUIDs

Lesson 53 - Working with Enumerations

Lesson 54 - Understanding the switch() Statement

Lesson 55 - First Pass at the Separation of Concerns Principle

Lesson 56 - Understanding Exception Handling

Lesson 57 - Understanding Global Exception Handling

Lesson 58 - Understanding Custom Exceptions

Lesson 59 - Creating a Database in Visual Studio

Lesson 60 - Creating an Entity Data Model

Lesson 61 - Displaying the DbSet Result in an ASP.NET GridView

Lesson 62 - Implementing a Button Command in a GridView

Lesson 63 - Using a Tools-Centric Approach to Building a Database Application

Lesson 64 - Using a Maintenance-Driven Approach to Building a Database Application

Lesson 65 - Creating a New Instance of an Entity and Persisting it to the Database

Lesson 66 - Package Management with NuGet

Lesson 67 - NuGet No-Commit Workflow

Lesson 68 - Introduction the Twitter Bootstrap CSS Framework

Lesson 69 - Mapping Enum Types to Entity Properties in the Framework Designer

Lesson 70 - Deploying the App to Microsoft Azure Web Services Web Apps

Papa Bob's Mega Challenge

Papa Bob's Mega Solution Part 1 - Setting up the Solution

Papa Bob's Mega Solution Part 2 - Adding an Order to the Database

Papa Bob's Mega Solution Part 3 - Passing an Order from the Presentation Layer

Papa Bob's Mega Solution Part 4 - Creating the Order Form

Papa Bob's Mega Solution Part 5 - Adding Enums

Papa Bob's Mega Solution Part 6 - Creating an Order with Validation

Papa Bob's Mega Solution Part 7 - Calculating the Order Price

Papa Bob's Mega Solution Part 8 - Displaying the Price to the User

Papa Bob's Mega Solution Part 9 - Creating the Order Management Page


Please login or register to add a comment