Separation Of Concerns (SOC)

In this example I’ve been learning about the separation of a program into layers. Along with doing some simple site database and Entity framework tasks. In this example there are the following     layers. A presentation layer, a domain layer, a data transfer layer (DTO for short), and a persistence layer. The flow of the program is the presentation layer makes calls to the domain layer. The domain layers might do some work, if not, then the domain layer will make calls to the persistence layer. The data transfer layers job is to only transfer data from the persistence layer to the domain layer.

SocProgram SocLayers SocDatabase

 
Default.aspx HTML code

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MyCustomers.Presentation.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:GridView ID="customersGridView" runat="server" BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3" GridLines="Vertical" OnRowCommand="customersGridView_RowCommand">
            <AlternatingRowStyle BackColor="#DCDCDC" />
            <Columns>
                <asp:ButtonField Text="View" />
            </Columns>
            <FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
            <HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
            <RowStyle BackColor="#EEEEEE" ForeColor="Black" />
            <SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
            <SortedAscendingCellStyle BackColor="#F1F1F1" />
            <SortedAscendingHeaderStyle BackColor="#0000A9" />
            <SortedDescendingCellStyle BackColor="#CAC9C9" />
            <SortedDescendingHeaderStyle BackColor="#000065" />
        </asp:GridView>
        <br />
        <br />
        <asp:Label ID="resultsLabel" runat="server"></asp:Label>
    
    </div>
    </form>
</body>
</html>

Not much to explain here. A basic page with a gridview and some display settings that I was messing with. More on the display setting when I get into Bootstrap.

 
Default.aspx code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyCustomers.Presentation
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Getting a list of customers by calling a methon in the DTO class 
            // of this project. This calling on the method in the Domain layer.
            List<DTO.MyCustomerDTO> customers = Domain.MyCustomersManager.GetCustomers();

            // Binding the gridview datasource to the customers list.
            customersGridView.DataSource = customers.ToList();
            customersGridView.DataBind();
        }

        protected void customersGridView_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            // Getting the gridview row object using the index number.
            GridViewRow row = customersGridView.Rows[Convert.ToInt32(e.CommandArgument)];

            // Getting the row objects GUID.
            Guid customerGuid = Guid.Parse(row.Cells[1].Text);

            // Getting the customer information thru the Domain layer.
            DTO.MyCustomerDTO customerInfo = Domain.MyCustomersManager.GetCustomerInfo(customerGuid);

            // Displaying the selected customer information.
            resultsLabel.Text = String.Format("{0} {1} {2} {3}",
                customerInfo.CustomerName,
                customerInfo.CustomerAddress,
                customerInfo.CustomerCity,
                customerInfo.CustomerState);
        }
    }
}

I’ve kept the main display page in the presentation layer because it presents the data to the user. The methods in here make calls to the domain layer to perform various tasks. Along with other methods to display the data. Like String.Format().

 
MyCustomerManager.cs code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MyCustomers;

namespace MyCustomers.Domain
{
    public class MyCustomersManager
    {
        // Method used to get a list of customers from the persistence layer.
        public static List<DTO.MyCustomerDTO> GetCustomers()
        {
            // Calling the persistence layer method to return a list of customers.
            // Then the DTO list that's returned will be sent to the presentation layer.
            List<DTO.MyCustomerDTO> customers = Persistence.MyCustomersRepository.GetCustomers();
            return customers;
        }

        // Method used to get the customer information from the persistence layer.
        public static DTO.MyCustomerDTO GetCustomerInfo(Guid customerGuid)
        {
            // Calling the persistence layer method to return the customer details.
            // Then return the DTO object back to the presentation layer.
            DTO.MyCustomerDTO customerInfo = Persistence.MyCustomersRepository.GetCustomerInfo(customerGuid);
            return customerInfo;
        }
    }
}

This class is really simple in this program. The methods make calls into the persistence layer.

 
MyCustomerDTO.cs code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyCustomers.DTO
{
    public class MyCustomerDTO
    {
        public System.Guid CustomerId { get; set; }
        public string CustomerName { get; set; }
        public string CustomerAddress { get; set; }
        public string CustomerCity { get; set; }
        public string CustomerState { get; set; }
        public string CustomerPostalCode { get; set; }
        public string CustomerNotes { get; set; }
    }
}

This class is a copy of the entities properties after the database and entity object were created in the persistence layer. Reason for this is perform data transfer of objects in a class outside of the persistence layer. This helps minimize calls to database objects in the persistence layer by filtering all requests thru one class. Instead of multiple classes making calls to the persistence layer at different times.

 
MyCustomersRepository.cs code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyCustomers.Persistence
{
    public class MyCustomersRepository
    {
        public static List<DTO.MyCustomerDTO> GetCustomers()
        {
            // Creating an object from the Entity data model and populating a list from 
            // that data.
            MyCustomersEntities db = new MyCustomersEntities();
            List<MyCustomer> databaseCustomers = db.MyCustomers.ToList();

            // Creating a list of objects defined from the DTO class with that data pulled
            // from the Entity data model list.
            List<DTO.MyCustomerDTO> dtoCustomers = new List<DTO.MyCustomerDTO>();
            
            // Looping thru the Entity data model list and populating the DTO
            // list.
            foreach (MyCustomer dbCustomer in databaseCustomers)
            {
                // Creating a DTO object and its properties/fields.
                DTO.MyCustomerDTO dtoCustomer = new DTO.MyCustomerDTO();
                dtoCustomer.CustomerId = dbCustomer.CustomerId;
                dtoCustomer.CustomerName = dbCustomer.CustomerName;
                dtoCustomer.CustomerAddress = dbCustomer.CustomerAddress;
                dtoCustomer.CustomerCity = dbCustomer.CustomerCity;
                dtoCustomer.CustomerState = dbCustomer.CustomerState;
                dtoCustomer.CustomerPostalCode = dbCustomer.CustomerPostalCode;
                dtoCustomer.CustomerNotes = dbCustomer.CustomerNotes;

                dtoCustomers.Add(dtoCustomer);
            }
            return dtoCustomers;
        }

        // Method used to locate a customer in the database.
        public static DTO.MyCustomerDTO GetCustomerInfo(Guid customerGuid)
        {
            // Creating an Entity object and locating the selected entry by the guid.
            MyCustomersEntities db = new MyCustomersEntities();
            MyCustomer customersDbInfo = db.MyCustomers.Find(customerGuid);

            // Creating a DTO object to populate the properies to pass back to the 
            // domain layer.
            DTO.MyCustomerDTO customerInfo = new DTO.MyCustomerDTO();
            customerInfo.CustomerId = customersDbInfo.CustomerId;
            customerInfo.CustomerName = customersDbInfo.CustomerName;
            customerInfo.CustomerAddress = customersDbInfo.CustomerAddress;
            customerInfo.CustomerCity = customersDbInfo.CustomerCity;
            customerInfo.CustomerState = customersDbInfo.CustomerState;
            customerInfo.CustomerPostalCode = customersDbInfo.CustomerPostalCode;
            customerInfo.CustomerNotes = customersDbInfo.CustomerNotes;     

            return customerInfo;
        }
    }
}

This class is where most of the work takes place when it comes to accessing the database. Again I’m forcing all the calls to come thru the layers down to this level and back. There are only 2 simple methods here right now that display all of the database information. The other method looks up a specific database object by using the unique GUID identifier.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s