Starting our .NET Core WebAPI Journey – Step 2
If you read my ASP.NET Core WebAPI Journey - Step 1, we
touched on the fact, we wanted to build our class library first as this will
really do most if not all of the business logic. We’re going to create this in
a .NET Standard library so we can start using this same library in both .NET
Core or .NET framework class libraries in this and future guides going forward.
Our business class library will start off doing three things.
·
Log generic topics into the database
·
Log emails to be sent
·
Send emails
Before the creation of the library itself, we need to model our database to store these values. This will be used for logging and our automated email queue.
Below is a high-level overview of all of the steps to create
this library. You can follow along but all of the code is available to download
at https://github.com/RichardWysocki/LunchandLearn.
Creating our Database
In this guide, we are going to use SQL Server. Why? As a Microsoft developer, this is typically
very familiar with you and also will allow us to transition to Azure easily, if
we want, in the future. I’m going to
keep the naming of the work in this guide as “LunchandLearn” in the event you
or I want to do this in the future.
You should be familiar with SQL Server but if not, Access Microsoft SQL Server Management Studio.
Right Click on Databases
and select New Database…
Create Database: LunchandLearn
We’re only going to
create two basic tables in this guide.
[LogId] [int] IDENTITY(1,1)
NOT NULL,
[Product] [varchar](100)
NULL, -- Application its coming from
[Type] [varchar](50)
NULL, -- Informational / Error
[Class] [varchar](50)
NULL,
[Method] [varchar](50)
NULL,
[Message] [varchar](4000)
NULL,
[Source] [varchar](4000)
NULL
)
ON [PRIMARY]
GO
CREATE
TABLE [dbo].[AutomatedEmails](
[EmailId] [int] IDENTITY(1,1)
NOT NULL,
[ToAddress] [varchar](100)
NULL,
[Name] [varchar](50)
NULL,
[Subject] [varchar](50)
NULL,
[Body] [varchar](4000)
NULL,
[EmailSent] [bit] NULL
)
ON [PRIMARY]
GO
Once you are done creating the tables, you should be able to
see them in your database. See below the
ones I created.
Before we’re done with the database, we must prepare and
setup a unique user to access your database from our services.
Expand Security
and select Login. Right Click on Login and select New Login…
Create your user as shown Below
Login Name: lunchandlearn
Select SQL Server authentication
Password: lunchandlearn123$
Creating our .NET Standard Library
Now for the exciting section of building our .NET Standard
library. Before we dive into the code,
I’m sure some people might be asking, Why
.NET Standard? I could have
easily created a .NET Core Library since I’m creating a .NET Core WebAPI
solution. The reason I wanted to move to
.NET Standard is because I can then use this code in either .NET Framework or
.NET Core. While I suspect I’ll be
migrating more and more work to .NET Core, I have so many legacy libraries in
.NET Framework I can’t immediately stop using all of it. I keep strategizing, how am I going to move
to .NET Core when all of my related class libraries are built on .NET
Framework. The goal in my mind is to recompile
all of these class libraries into .NET Standard. Then as each solution has all of its
components upgraded to .NET Standard, the main solution, WebAPI, Website, etc.
could then be migrated to .NET Core.
If your new to .NET Standard, this is a very nice articles
that talks about the differences. It’s
getting a little old but it’s still a good intro. https://dotnetcoretutorials.com/2017/01/13/net-standard-vs-net-core-whats-difference/. In addition to that, Microsoft’s
documentation on .NET Standard is extremely good. https://docs.microsoft.com/en-us/dotnet/standard/net-standard I really like the Grid that shows the
supported frameworks per .NET Standard version.
In our solution, we’re going to be creating a .NET Standard Library on
version 2.0. This is compatible with
.NET framework 4.6.1+ as well as .NET Core 2.0.
This may be important depending on the hardware or solution you are
building. For example, if you have a
more legacy .NET framework app running on .NET 4.5, you can’t use a .NET
Standard 2.0 Library. You would need to create a .NET Standard library using
version 1.1
Let’s start creating the.NET Standard Solution.
Open Visual Studio 2017 (I’m on version 15.7.2). In my examples below, I will be adding this
project into our Windows IoT Background LunchandLearn solution. You can create a new solution or add this
within an existing solution.
Add -> New Project.
You can select .NET Standard and create your class as shown below. I’m naming this project:
* Once your project is created, you can delete the “Class1.cs”
class
Before we start coding we’re going to add in our
references. As we discussed in our Step
1 article, we highlighted that we would be using Entity Framework. Let’s add that to our project.
Expand the project and right click on Dependencies and selecting Manage
NuGet References. Browse for the Nuget package shown below. As you can see on the dependencies, it is
compatible with .NET Standard v2.0.
Click Install and then you may
be prompted to add the Dependencies as well as to Accept the License agreement.
·
Nuget Package Microsoft.EntityFrameworkCore.SqlServer
Now that you installed Entity Framework, you might have been
wondering Why am I using this or
What is Entity Framework. The main reason I’ve started to use Entity
Framework is because it removes so much complexity of accessing the database. It seems like over the years, one of the
first things I do is write a data access class for my projects. I was not wise enough to create a library for
this. With entity framework, it takes that load off of me and I can concentrate
more on the business logic of the solution. As is typical these days, Microsoft
has done a very good job on their documentation. I recommend you read/browse
these links below. In our example, we’ll create the Model classes that relate
to our tables and then a database context which groups all of the models
together.
I like to group the Models togethers so start by creating a
Model’s folder
Right click on the project and select Add -> New Folder and name it Model. Once that is done,
add in two new classes which relate to our tables.
·
Add class -> LogInformation.cs
·
Add class -> AutomatedEmails.cs
Once these classes are created, you will want to create
properties within each of them that represent the tables that we created
earlier. Below is a screen shot of our AutomatedEmails queuing table. You can see how both of these classes are
created within the Model folder.
Next, we’re going to create our database context classes. If
you reviewed the documentation above, they show examples where I could have named
these classes like ServiceContext or around the functionality I’m coding but
I’ve always seen this as accessing my data layer. In the event I was accessing
more than one database, then I would create more than one context. As we create
these new classes, we will create interfaces for a future article on doing unit
testing.
Add class -> IDBContext.cs
Add class -> DBContext.cs
Below I have added in these classes and updated them with the models I’m references. In addition to that, I have passed into the constructor some additional options. This will be used later to pass in the connection string.
Now that our database context is created, we can start the
process of creating our data access layer.
My current pattern is basically to create CRUD (Create, Read, Update,
Delete) operations but it typically depends on the functions I need. Our initial
data access class will be to log data operations. Since this information is
logging, we’re not going to Update or Delete.
We’re only going to need Create and Read (one & many) methods.
Let’s start with the Interface: Add -> New Item. Add a new interface called ILogInformationDataAccess.cs
Below are the methods we’re going to start with:
IList Get();
LogInformation Get(int id);
Next add in the LogInformationDataAccess.cs
class. Inherit the interface methods and implement the missing members. Below is one way to do this using ReSharper.
Now add in the Information to Create and Read the logging
information. In this example, we’re using dependency injection to inject the database
context into the class so that it could be mocked later. The examples below show the entire picture of
getting the entire list of Logging, one log record or inserting a log record
into the database.
The second data access class we want to create is our email
data access. In this class we want to
perform our typical CRUD operations as well as just get a list of emails that
have been sent or not sent. In your project, add in an interface class, IEmailDataAccess.cs, with the following
methods:
IList Get();
IList Get( bool emailSent);
AutomatedEmails Get(int id);
AutomatedEmails Insert(AutomatedEmails
email);
bool Update(AutomatedEmails update);
Besides accessing the database, this library will send
emails to people. Microsoft has some good documentation on sending emails. There are also a lot of examples online. I
will assume you are familiar with this as I will not be discussing how the
SmtpClient libraries work in detail. In order to do this, we must configure certain
settings like the SMTP Server, Port, authentication, etc.
Create the interface file for the settings we’ll be passing
into the Email Sender class.
Add -> New Item…. IEmailConfiguration.cs
class file. We’re going to add the
following configurations.
Once the configuration classes are created, you can focus on
the actual functionality to send the email. We’re going to create an EmailSender class which only has one
method which sends emails.
Add -> New Item, select interface and name your interface
IEmailSender.cs. Add the following code to create the
interface as shown below.
Once the interface is complete, create a new class called EmailSender and implement the members
from the interface above. You will want
to inject into the class your email configuration class. In a future guide on unit
testing, we may enhance this method for the SmtpClient to be injected as well. Below is our code below.
WOW, we’re done!
Everything should compile. I
didn’t think you would do everything but I wanted to show you the steps as if
you would do it. To Download the latest
code, go to: https://github.com/RichardWysocki/LunchandLearn.
This code will be the most recent so you may see some slight enhancements per
future articles.
In our next article, we’ll create the .NET Core WebAPI
Service. Since this one was so big and
long, lets break it into smaller components.
If I’ve helped you at all, don’t forget…. please send me
feedback. We’re all on this
#LearnGrowShare journey together so if you see something that would help our
journey together please speak up. We’re
only as good as our experiences so look forward to you helping to make me a
better software Developer/Engineer.
Comments