I finished! On to the next chapter

Outline

Demo: Implement Async Process

In the Conduit.Repositories Project

Inject ConduitContext
  • Add the Conduit.Data as a project reference Conduit.Repositories
  • Add a private member called "Context" make it type ConduitContext
  • Resolve the namespace
Modify the Constructor
  • Add a parameter call "context"
  • In the body the constructor method assign the value of "context" to "Context"
Modify RegisterUser Method
  • Call a non-existing method named UserExist(register) and assign it to var userExist
  • Hover over the error and [Show Potential Fixes], select [Generate Method]
(Optional) Move newly generated method to above RegisterUser method

Typical order of class member are as follows:

  • Private Members
  • Private Methods
  • Public Methods
  • Constructors

There's more but for now this is good enough

Modify UserExist Method
  • Make an Async call to check if any Account/Person records exist with the registering Email or Username
  • Hover over the errors and resolve as needed
  • Results: You end up with an async method
Modify RegisterUser Method
  • Add await to the method call UserExistAsync(register)
  • Hover over error and fix as needed
  • Results: You end up with an async method
Modify RegisterUserAsync Method
  • Add an if statement to evaluate userExist
  • throw an exception called UserExistException
  • Add a message "The email or user name is already in use."

In the Conduit.Models Project

Add following content
  • New folder name Exceptions
  • New class name UserExistException
    • Make is public
    • Derived from Exception
    • Add constructor with message parameter passed into the base class
    • In Conduit.Repositories.AccountRepository, bring in the new namespace

Here is what the AccountRepository class code should look like:

using Conduit.Data;
using Conduit.Models.Exceptions;
using Conduit.Models.Requests;
using Conduit.Models.Responses;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace Conduit.Repositories
{
    public class AccountRepository : IAccountRepository
    {
        private ConduitContext Context;
        private ILogger<AccountRepository> Logger;

        private async Task<bool> UserExistAsync(Register register)
        {
            var result = await Context
                                .Accounts
                                .AnyAsync(e => e.Email == register.Email || e.Person.UserName == register.UserName)
                                .ConfigureAwait(false);
            return result;
        }

        public async Task<User> RegisterUserAsync(Register register)
        {
            bool userExist = await UserExistAsync(register);
            if (userExist)
            {
                throw new UserExistException("The email or user name is already in use.");
            }
            User user = new User
            {
                Bio = "no bio yet",
                Email = register.Email,
                Image = "no image yet",
                Token = "no token yet",
                UserName = register.UserName
            };
            return user;
        }

        public AccountRepository(ConduitContext context, ILogger<AccountRepository> logger)
        {
            Context = context;
            Logger = logger;
        }
    }
}

Note: Interface class has an erorr that will be fixed in the next demo.