Creating a Newsletter Manager with Hangfire

Creating a Bulk-Email Management System II – Models & Entities

As detailed in my background post, the underlying infrastructure that will be used by different clients is a set of APIs for managing subscriptions and newsletters (note that I use the words emails and newsletter interchangeably). It’ll hold all the necessary business logic for managing subscriptions, newsletters and email requests. This is split across different sub-projects for organizational purposes. In this post, I walk through the first of 5 projects; the data class library project.

First things first…

My approach is usually to create a Blank Solution under which all my projects will come under. To do that, Open Visual Studio, select ‘Create New Project’ and select ‘Blank Solution’ from the list of project templates. Give it a name and save; mine’s named BabaFunkeEmailManager.

1. BabaFunkeEmailManager.Data Project

This is a C# Class Library project for handling all data related models and Azure Table entities. Because we’re using Azure Table Storage for our data store, the entities represent the corresponding tables in the storage, hence they extend the TableEntity class. You could think of the models as DTOs in this sense since they represent a conceptual layer between the data store (Azure Table Storage) and the service, hence the use of mappers as will be seen in the service project. So, every entity in our project has a corresponding model. However, not all models have corresponding entities as some are simply for presentation purposes.

Step 1 – Add a Class Library Project for the Data. 

Right-Click the blank solution and select ‘Add > New Project’ from the context menu. Select the ‘Class Library’ project option; make sure it’s C# and targets .Net Standard or .Net Core. I name mine BabaFunkeEmailManager.Data. 

Step 2 – Create the Models

The models represent the objects for our system. The first 3 – Subscriber, Newsletter and EmailResponse – are self-explanatory.

RequestHeader.cs – every request to send out a newsletter to a set of recipients will be done using an instance of this object. Hence, it’s the unit of work that captures the request at a broader level, hence the Id of the Newsletter to send and the Subscriber’s SubCategory to send to. The Subscriber’s SubCategory is a way of grouping subscribers.

ServiceResponse.cs – the service response does not have a corresponding entity as it’s only for presentational purpose. I find it convenient to return an object like this from my APIs.

RequestDetail.cs – this also does not have a corresponding entity. Instead, it represents the granular details of the RequestHeader. For example, while a RequestHeader instance contains the Id of a specific newsletter and a Subscriber’s SubCategory, the RequestDetail instance is created for each subscriber in that SubCategory. It is this detail that is sent over to a MessageQueue as we’ll see later.

Step 3 – Create the Entities. 

One of the way to minimise cost is by using a simple data store like Azure Table Storage. I explain more about Azure Table Storage in my post on creating an automated invoice manager. Install the Microsoft.Azure.Cosmos.Table Nuget package then create the classes below. These classes have corresponding models above so they have similar properties. The only difference is that the entities extend Cosmos Table’s TableEntity class which provides us with a Rowkey and PartitionKey properties; must haves for table entities. What you may observe is the absence of some properties e.g. Email and Category in the SubscriberEntity. This is because those properties will be mapped to the RowKey and PartitionKey respectively.

Conclusion

That’s it for the Data as the first parts of our shared project. In Part III, I focus on the services. Note that the project is available on Github for ease of replicating.