C# Classes For A CRM Application

C# Classes For A CRM Application

So far we have been looking at the specifics of how to create a class in C#, then add properties and methods to it. Now we want to add additional classes to the application. This is a customer relationship management type application so we’ll need things like an Order class, a Product class, an OrderItem class, and maybe a few others. In this tutorial we’ll start building out those classes to work with our existing Customer class while paying attention to thins like Coupling, Cohesion, Separation of Concerns, and Design Patterns.

First let’s define Coupling, Cohesion, Separation of Concerns, and Design Patterns.

  • Coupling is the degree to which classes are dependent on each other.
  • Cohesion is the degree to which members of the class relate to the purpose of the class.
  • Separation of Concerns tells us to decompose an application into parts with minimal overlap. Each part is responsible for a separate concern.
  • Design Patterns are common practices for defining appropriate classes and their associated relationships.

The Product Class

The code for our Product class is shown below and the first thing we can see is that it has a constructor which accepts an integer id representing the productId. It also has several properties that we can use to represent a product. What things would a product have? It would have things like a CurrentPrice, a ProductId, a ProductDescription, and a ProductName. Additionally, there is a Validate() method on the class which validates the integrity of the ProductName as well as the CurrentPrice. We also have a Retrieve() and Save() method. The class file name is Product.cs.


The Order Class

The Order class also makes use of a default constructor, as well as a secondary constructor that accepts an integer representing the orderId. The Order class has two properties of OrderDate and OrderId. We see those same methods too of Retrieve(), Save() and Validate(). The file name for the Order class is Order.cs.


The OrderItem Class

The last class in the outline for our CRM application will be the OrderItem class and it is listed below. Everything looks pretty good, but we do see that there are many methods that all of these classes have. We may want to refactor those a bit. Following convention, the OrderItem class has a file name of OrderItem.cs.


Refactoring Class Responsibilities

So far we have a Customer, Product, Order, and OrderItem class. It’s a good start to represent a basic CRM application. There are a couple of problems however. All of these classes have a Retrieve() and Save() method that could be extracted to a repository class. In addition, we should remove some responsibility from the Customer class and place it in an Address class. Let’s start fixing these now.


The Address Class

Below is the code for the Address class and is found in Address.cs. It is used to represent an Address with the properties of AddressId, AddressType, StreetLine1, StreetLine2, City, State, PostalCode, and Country. Just enough to do its job.


Creating Repository Classes For Data Persistence

The original classes above can benefit from removing the Retrieve() and Save() methods from them. Repository classes can handle the interaction with the database. This logic does not need to be recreated in every single class like it is above. It is better to extract that logic out and put it in its own repository. Using a repository pattern is a very popular convention in object oriented programming and is found in C#, Java, PHP, and so on.


The CustomerRepository Class

All we need to do in this class is to cut and paste the Retrieve() and Save() methods from the Customer class into this repository class. This way the work of interacting with the database is put in its own Class for better separation of concerns. Its file name is CustomerRepository.cs.


The OrderRepository Class

We can also create an OrderRepository class to handle interacting with the data store, moving that function out of the base Order class. So again, go ahead and move the code for Retrieve() and Save() out of the Order class, and place them now in the OrderRepository class here. Note that in all of these example repository classes so far, we are simply hard coding in some data to represent an Order, or a Product, etc. The actual code to interact with a database can be added later. For now we set things up this way, and we can even create some automated tests to ensure the code works. Below is OrderRepository.cs.


The Product Repository Class

The class is set to public, and again we move the Retrieve() and Save() methods out of the Product class and into this ProductRepository class. Those methods once again just use some simple hard coded data to simulate working with a database. Here is the ProductRepository.cs file.


The AddressRepository Class

The final repository class we can create is the AddressRepository.cs class. This one is a little bit more involved as it can retrieve a single address or a list of addresses for a customer. The RetrieveByCustomerId() method returns an IEnumerable. An IEnumerable is the recommended way to return a sequence of data since the results provide more flexibility for the callers of the method. This method takes as a parameter, the customers id which is an integer value.


Testing The CustomerRepository Class

We can test the repository classes using code similar to what we see here. This code tests the CustomerRepository class, and you could create similar classes to test both the OrderRepository and ProductRepository classes.

Running the test is giving us a big thumbs up!
C# repository pattern test


C# Classes For A CRM Application Summary

In this tutorial we created some classes to work with a CRM type application in C#. Once the classes were created, we evaluated each class to see if we could simplify to reduce responsibilities. We found that we could, and extracted some logic to associated repository classes. Taking this approach minimizes coupling, maximizes cohesion, simplifies maintenance, and helps make the code more testable. We’ll see how these classes work together soon when we talk about the relationships between classes.