├── .gitattributes
├── ClubMembershipApplication.sln
├── ClubMembershipApplication
├── ClubMembershipApplication.csproj
├── CommonOutputFormat.cs
├── CommonOutputText.cs
├── Data
│ ├── ClubMembershipDbContext.cs
│ ├── ILogin.cs
│ ├── IRegister.cs
│ ├── LoginUser.cs
│ └── RegisterUser.cs
├── Factory.cs
├── FieldValidators
│ ├── FieldConstants.cs
│ ├── IFieldValidator.cs
│ └── UserRegistrationValidator.cs
├── Models
│ └── User.cs
├── Program.cs
└── Views
│ ├── IView.cs
│ ├── MainView.cs
│ ├── UserLoginView.cs
│ ├── UserRegistrationView.cs
│ └── WelcomeUserView.cs
├── FieldValidatorAPI
├── CommonFieldValidatorFunctions.cs
├── CommonRegularExpressionValidationPatterns.cs
└── FieldValidatorAPI.csproj
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/ClubMembershipApplication.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29326.143
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClubMembershipApplication", "ClubMembershipApplication\ClubMembershipApplication.csproj", "{E256C6B4-EE69-4594-B3AD-25D3BFC70ABC}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FieldValidatorAPI", "FieldValidatorAPI\FieldValidatorAPI.csproj", "{AD0BB2E6-D1CA-4AB9-AB26-48331D576F27}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {E256C6B4-EE69-4594-B3AD-25D3BFC70ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {E256C6B4-EE69-4594-B3AD-25D3BFC70ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {E256C6B4-EE69-4594-B3AD-25D3BFC70ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {E256C6B4-EE69-4594-B3AD-25D3BFC70ABC}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {AD0BB2E6-D1CA-4AB9-AB26-48331D576F27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {AD0BB2E6-D1CA-4AB9-AB26-48331D576F27}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {AD0BB2E6-D1CA-4AB9-AB26-48331D576F27}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {AD0BB2E6-D1CA-4AB9-AB26-48331D576F27}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {3A879525-C980-49D0-85F1-BC2219796AEC}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/ClubMembershipApplication.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.0
6 |
7 |
8 |
9 |
10 |
11 | all
12 | runtime; build; native; contentfiles; analyzers; buildtransitive
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/CommonOutputFormat.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ClubMembershipApplication
6 | {
7 | public enum FontTheme
8 | {
9 | Default,
10 | Danger,
11 | Success
12 | }
13 | public static class CommonOutputFormat
14 | {
15 | public static void ChangeFontColor(FontTheme fontTheme)
16 | {
17 | if (fontTheme == FontTheme.Danger)
18 | {
19 | Console.BackgroundColor = ConsoleColor.Red;
20 | Console.ForegroundColor = ConsoleColor.White;
21 | }
22 | else if (fontTheme == FontTheme.Success)
23 | {
24 | Console.BackgroundColor = ConsoleColor.Green;
25 | Console.ForegroundColor = ConsoleColor.White;
26 | }
27 | else
28 | {
29 | Console.ResetColor();
30 | }
31 | }
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/CommonOutputText.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ClubMembershipApplication
6 | {
7 | public static class CommonOutputText
8 | {
9 | private static string MainHeading
10 | {
11 | get {
12 | string heading = "Cycling Club";
13 | return $"{heading}{Environment.NewLine}{new string('-',heading.Length)}";
14 | }
15 | }
16 |
17 | private static string RegistrationHeading
18 | {
19 | get {
20 | string heading = "Register";
21 | return $"{heading}{Environment.NewLine}{new string('-', heading.Length)}";
22 | }
23 | }
24 | private static string LoginHeading
25 | {
26 | get
27 | {
28 | string heading = "Login";
29 | return $"{heading}{Environment.NewLine}{new string('-', heading.Length)}";
30 | }
31 | }
32 |
33 | public static void WriteMainHeading()
34 | {
35 | Console.Clear();
36 | Console.WriteLine(MainHeading);
37 | Console.WriteLine();
38 | Console.WriteLine();
39 | }
40 | public static void WriteLoginHeading()
41 | {
42 | Console.WriteLine(LoginHeading);
43 | Console.WriteLine();
44 | Console.WriteLine();
45 | }
46 | public static void WriteRegistrationHeading()
47 | {
48 | Console.WriteLine(RegistrationHeading);
49 | Console.WriteLine();
50 | Console.WriteLine();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Data/ClubMembershipDbContext.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.Models;
2 | using Microsoft.EntityFrameworkCore;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace ClubMembershipApplication.Data
8 | {
9 | public class ClubMembershipDbContext:DbContext
10 | {
11 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
12 | {
13 | optionsBuilder.UseSqlite($"Data Source={AppDomain.CurrentDomain.BaseDirectory}ClubMembershipDb.db");
14 | base.OnConfiguring(optionsBuilder);
15 | }
16 |
17 | public DbSet Users { get; set; }
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Data/ILogin.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace ClubMembershipApplication.Data
7 | {
8 | public interface ILogin
9 | {
10 | User Login(string emailAddress, string password);
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Data/IRegister.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ClubMembershipApplication.Data
6 | {
7 | public interface IRegister
8 | {
9 | bool Register(string[] fields);
10 | bool EmailExists(string emailAddress);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Data/LoginUser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ClubMembershipApplication.Models;
5 | using System.Linq;
6 |
7 | namespace ClubMembershipApplication.Data
8 | {
9 | public class LoginUser : ILogin
10 | {
11 | public User Login(string emailAddress, string password)
12 | {
13 | User user = null;
14 |
15 | using (var dbContext = new ClubMembershipDbContext())
16 | {
17 | user = dbContext.Users.FirstOrDefault(u => u.EmailAddress.Trim().ToLower() == emailAddress.Trim().ToLower() && u.Password.Equals(password));
18 | }
19 | return user;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Data/RegisterUser.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using ClubMembershipApplication.FieldValidators;
6 | using System.Linq;
7 |
8 | namespace ClubMembershipApplication.Data
9 | {
10 | public class RegisterUser : IRegister
11 | {
12 | public bool EmailExists(string emailAddress)
13 | {
14 | bool emailExists = false;
15 |
16 | using (var dbContext = new ClubMembershipDbContext())
17 | {
18 | emailExists = dbContext.Users.Any(u => u.EmailAddress.ToLower().Trim() == emailAddress.Trim().ToLower());
19 | }
20 | return emailExists;
21 | }
22 |
23 | public bool Register(string[] fields)
24 | {
25 | using (var dbContext = new ClubMembershipDbContext())
26 | {
27 | User user = new User
28 | {
29 | EmailAddress = fields[(int)FieldConstants.UserRegistrationField.EmailAddress],
30 | FirstName = fields[(int)FieldConstants.UserRegistrationField.FirstName],
31 | LastName = fields[(int)FieldConstants.UserRegistrationField.LastName],
32 | Password = fields[(int)FieldConstants.UserRegistrationField.Password],
33 | DateOfBirth = DateTime.Parse(fields[(int)FieldConstants.UserRegistrationField.DateOfBirth]),
34 | PhoneNumber = fields[(int)FieldConstants.UserRegistrationField.PhoneNumber],
35 | AddressFirstLine = fields[(int)FieldConstants.UserRegistrationField.AddressFirstLine],
36 | AddressSecondLine = fields[(int)FieldConstants.UserRegistrationField.AddressSecondLine],
37 | AddressCity = fields[(int)FieldConstants.UserRegistrationField.AddressCity],
38 | PostCode = fields[(int)FieldConstants.UserRegistrationField.PostCode]
39 |
40 | };
41 |
42 | dbContext.Users.Add(user);
43 |
44 | dbContext.SaveChanges();
45 | }
46 | return true;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Factory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ClubMembershipApplication.Views;
5 | using ClubMembershipApplication.Data;
6 | using ClubMembershipApplication.FieldValidators;
7 |
8 | namespace ClubMembershipApplication
9 | {
10 | public static class Factory
11 | {
12 | public static IView GetMainViewObject()
13 | {
14 | ILogin login = new LoginUser();
15 | IRegister register = new RegisterUser();
16 | IFieldValidator userRegistrationValidator = new UserRegistrationValidator(register);
17 | userRegistrationValidator.InitialiseValidatorDelegates();
18 |
19 | IView registerView = new UserRegistrationView(register, userRegistrationValidator);
20 | IView loginView = new UserLoginView(login);
21 | IView mainView = new MainView(registerView, loginView);
22 |
23 | return mainView;
24 |
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/FieldValidators/FieldConstants.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ClubMembershipApplication.FieldValidators
6 | {
7 | public class FieldConstants
8 | {
9 | public enum UserRegistrationField
10 | {
11 | EmailAddress,
12 | FirstName,
13 | LastName,
14 | Password,
15 | PasswordCompare,
16 | DateOfBirth,
17 | PhoneNumber,
18 | AddressFirstLine,
19 | AddressSecondLine,
20 | AddressCity,
21 | PostCode
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/FieldValidators/IFieldValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ClubMembershipApplication.FieldValidators
6 | {
7 | public delegate bool FieldValidatorDel(int fieldIndex, string fieldValue, string[] fieldArray, out string fieldInvalidMessage);
8 | public interface IFieldValidator
9 | {
10 | void InitialiseValidatorDelegates();
11 | string[] FieldArray { get; }
12 | FieldValidatorDel ValidatorDel { get; }
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/FieldValidators/UserRegistrationValidator.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.Data;
2 | using FieldValidatorAPI;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace ClubMembershipApplication.FieldValidators
8 | {
9 | public class UserRegistrationValidator:IFieldValidator
10 | {
11 | const int FirstName_Min_Length = 2;
12 | const int FirstName_Max_Length = 100;
13 | const int LastName_Min_Length = 2;
14 | const int LastName_Max_Length = 100;
15 |
16 | delegate bool EmailExistsDel(string emailAddress);
17 |
18 | FieldValidatorDel _fieldValidatorDel = null;
19 |
20 | RequiredValidDel _requiredValidDel = null;
21 | StringLengthValidDel _stringLenthValidDel = null;
22 | DateValidDel _dateValidDel = null;
23 | PatternMatchValidDel _patternMatchValidDel = null;
24 | CompareFieldsValidDel _compareFieldsValidDel = null;
25 |
26 | EmailExistsDel _emailExistsDel = null;
27 |
28 | string[] _fieldArray = null;
29 | IRegister _register = null;
30 |
31 | public string[] FieldArray
32 | {
33 | get
34 | {
35 | if (_fieldArray == null)
36 | _fieldArray = new string[Enum.GetValues(typeof(FieldConstants.UserRegistrationField)).Length];
37 | return _fieldArray;
38 | }
39 | }
40 |
41 | public FieldValidatorDel ValidatorDel => _fieldValidatorDel;
42 |
43 | public UserRegistrationValidator(IRegister register)
44 | {
45 | _register = register;
46 | }
47 |
48 | public void InitialiseValidatorDelegates()
49 | {
50 | _fieldValidatorDel = new FieldValidatorDel(ValidField);
51 | _emailExistsDel = new EmailExistsDel(_register.EmailExists);
52 |
53 | _requiredValidDel = CommonFieldValidatorFunctions.RequiredFieldValidDel;
54 | _stringLenthValidDel = CommonFieldValidatorFunctions.StringLengthFieldValidDel;
55 | _dateValidDel = CommonFieldValidatorFunctions.DateFieldValidDel;
56 | _patternMatchValidDel = CommonFieldValidatorFunctions.PatternMatchValidDel;
57 | _compareFieldsValidDel = CommonFieldValidatorFunctions.FieldsCompareValidDel;
58 | }
59 |
60 | private bool ValidField(int fieldIndex, string fieldValue, string[] fieldArray, out string fieldInvalidMessage)
61 | {
62 |
63 | fieldInvalidMessage = "";
64 |
65 | FieldConstants.UserRegistrationField userRegistrationField = (FieldConstants.UserRegistrationField)fieldIndex;
66 |
67 | switch (userRegistrationField)
68 | {
69 | case FieldConstants.UserRegistrationField.EmailAddress:
70 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
71 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_patternMatchValidDel(fieldValue,CommonRegularExpressionValidationPatterns.Email_Address_RegEx_Pattern)) ? $"You must enter a valid email address{Environment.NewLine}" : fieldInvalidMessage;
72 | fieldInvalidMessage = (fieldInvalidMessage == "" && _emailExistsDel(fieldValue)) ? $"This email address already exists. Please try again{Environment.NewLine}" : fieldInvalidMessage;
73 |
74 | break;
75 | case FieldConstants.UserRegistrationField.FirstName:
76 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
77 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_stringLenthValidDel(fieldValue, FirstName_Min_Length,FirstName_Max_Length)) ? $"The length for field: {Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)} must be between {FirstName_Min_Length} and {FirstName_Max_Length}{Environment.NewLine}" : fieldInvalidMessage;
78 | break;
79 | case FieldConstants.UserRegistrationField.LastName:
80 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
81 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_stringLenthValidDel(fieldValue, LastName_Min_Length, LastName_Max_Length)) ? $"The length for field: {Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)} must be between {LastName_Min_Length} and {LastName_Max_Length}{Environment.NewLine}" : fieldInvalidMessage;
82 | break;
83 | case FieldConstants.UserRegistrationField.Password:
84 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
85 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_patternMatchValidDel(fieldValue, CommonRegularExpressionValidationPatterns.Strong_Password_RegEx_Pattern)) ? $"Your password must contain at least 1 small-case letter, 1 capital letter, 1 special character and the length should be between 6 - 10 characters{Environment.NewLine}" : fieldInvalidMessage;
86 | break;
87 | case FieldConstants.UserRegistrationField.PasswordCompare:
88 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
89 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_compareFieldsValidDel(fieldValue,fieldArray[(int)FieldConstants.UserRegistrationField.Password])) ? $"Your entry did not match your password{Environment.NewLine}" : fieldInvalidMessage;
90 | break;
91 | case FieldConstants.UserRegistrationField.DateOfBirth:
92 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
93 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_dateValidDel(fieldValue, out DateTime validDateTime)) ? $"You did not enter a valid date" : fieldInvalidMessage;
94 | break;
95 | case FieldConstants.UserRegistrationField.PhoneNumber:
96 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
97 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_patternMatchValidDel(fieldValue,CommonRegularExpressionValidationPatterns.Uk_PhoneNumber_RegEx_Pattern)) ? $"You did not enter a valid UK phone number{Environment.NewLine}" : fieldInvalidMessage;
98 | break;
99 | case FieldConstants.UserRegistrationField.AddressFirstLine:
100 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
101 | break;
102 | case FieldConstants.UserRegistrationField.AddressSecondLine:
103 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
104 | break;
105 | case FieldConstants.UserRegistrationField.AddressCity:
106 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
107 | break;
108 | case FieldConstants.UserRegistrationField.PostCode:
109 | fieldInvalidMessage = (!_requiredValidDel(fieldValue)) ? $"You must enter a value for field:{Enum.GetName(typeof(FieldConstants.UserRegistrationField), userRegistrationField)}{Environment.NewLine}" : "";
110 | fieldInvalidMessage = (fieldInvalidMessage == "" && !_patternMatchValidDel(fieldValue, CommonRegularExpressionValidationPatterns.Uk_Post_Code_RegEx_Pattern)) ? $"You did not enter a valid UK post code{Environment.NewLine}" : fieldInvalidMessage;
111 | break;
112 | default:
113 | throw new ArgumentException("This field does not exists");
114 |
115 | }
116 |
117 | return (fieldInvalidMessage == "");
118 |
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Models/User.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations.Schema;
4 | using System.Text;
5 |
6 | namespace ClubMembershipApplication.Models
7 | {
8 | public class User
9 | {
10 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
11 | public int Id { get; set; }
12 |
13 | public string EmailAddress { get; set; }
14 |
15 | public string FirstName { get; set; }
16 |
17 | public string LastName { get; set; }
18 |
19 | public string Password { get; set; }
20 |
21 | public DateTime DateOfBirth { get; set; }
22 |
23 | public string PhoneNumber { get; set; }
24 |
25 | public string AddressFirstLine { get; set; }
26 |
27 | public string AddressSecondLine { get; set; }
28 |
29 | public string AddressCity { get; set; }
30 |
31 | public string PostCode { get; set; }
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ClubMembershipApplication.Views;
3 | namespace ClubMembershipApplication
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | IView mainView = Factory.GetMainViewObject();
10 | mainView.RunView();
11 |
12 | Console.ReadKey();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Views/IView.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.FieldValidators;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace ClubMembershipApplication.Views
7 | {
8 | public interface IView
9 | {
10 | void RunView();
11 | IFieldValidator FieldValidator { get; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Views/MainView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ClubMembershipApplication.FieldValidators;
5 |
6 |
7 | namespace ClubMembershipApplication.Views
8 | {
9 | class MainView : IView
10 | {
11 | public IFieldValidator FieldValidator => null;
12 |
13 | IView _registerView = null;
14 | IView _loginView = null;
15 | public MainView(IView registerView, IView loginView)
16 | {
17 | _registerView = registerView;
18 | _loginView = loginView;
19 | }
20 | public void RunView()
21 | {
22 | CommonOutputText.WriteMainHeading();
23 |
24 | Console.WriteLine("Please press 'l' to login or if you are not yet registered please press 'r'");
25 |
26 | ConsoleKey key = Console.ReadKey().Key;
27 |
28 | if (key == ConsoleKey.R)
29 | {
30 | RunUserRegistrationView();
31 | RunLoginView();
32 | }
33 | else if (key == ConsoleKey.L)
34 | {
35 | RunLoginView();
36 | }
37 | else
38 | {
39 | Console.Clear();
40 | Console.WriteLine("Goodbye");
41 | Console.ReadKey();
42 |
43 | }
44 |
45 | }
46 |
47 | private void RunUserRegistrationView()
48 | {
49 | _registerView.RunView();
50 | }
51 |
52 | private void RunLoginView()
53 | {
54 | _loginView.RunView();
55 | }
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Views/UserLoginView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ClubMembershipApplication.Data;
5 | using ClubMembershipApplication.FieldValidators;
6 | using ClubMembershipApplication.Models;
7 |
8 | namespace ClubMembershipApplication.Views
9 | {
10 | public class UserLoginView : IView
11 | {
12 | ILogin _loginUser = null;
13 | public IFieldValidator FieldValidator => null;
14 |
15 | public UserLoginView(ILogin login)
16 | {
17 | _loginUser = login;
18 | }
19 | public void RunView()
20 | {
21 | CommonOutputText.WriteMainHeading();
22 |
23 | CommonOutputText.WriteLoginHeading();
24 |
25 | Console.WriteLine("Please enter your email address");
26 |
27 | string emailAddress = Console.ReadLine();
28 |
29 | Console.WriteLine("Please enter your password");
30 |
31 | string password = Console.ReadLine();
32 |
33 | User user = _loginUser.Login(emailAddress,password);
34 |
35 | if (user != null)
36 | {
37 | WelcomeUserView welcomeUserView = new WelcomeUserView(user);
38 | welcomeUserView.RunView();
39 | }
40 | else
41 | {
42 | Console.Clear();
43 | CommonOutputFormat.ChangeFontColor(FontTheme.Danger);
44 | Console.WriteLine("The credentials that you entered do not match any of our records");
45 | CommonOutputFormat.ChangeFontColor(FontTheme.Default);
46 | Console.ReadKey();
47 | }
48 |
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Views/UserRegistrationView.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.Data;
2 | using ClubMembershipApplication.FieldValidators;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace ClubMembershipApplication.Views
8 | {
9 | public class UserRegistrationView:IView
10 | {
11 | IFieldValidator _fieldValidator = null;
12 |
13 | IRegister _register = null;
14 |
15 | public IFieldValidator FieldValidator { get => _fieldValidator;}
16 |
17 | public UserRegistrationView(IRegister register, IFieldValidator fieldValidator)
18 | {
19 | _fieldValidator = fieldValidator;
20 | _register = register;
21 | }
22 |
23 | public void RunView()
24 | {
25 | CommonOutputText.WriteMainHeading();
26 | CommonOutputText.WriteRegistrationHeading();
27 |
28 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.EmailAddress] = GetInputFromUser(FieldConstants.UserRegistrationField.EmailAddress,"Please enter your email address: ");
29 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.FirstName] = GetInputFromUser(FieldConstants.UserRegistrationField.FirstName, "Please enter your first name: ");
30 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.LastName] = GetInputFromUser(FieldConstants.UserRegistrationField.LastName, "Please enter your last name: ");
31 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.Password] = GetInputFromUser(FieldConstants.UserRegistrationField.Password, $"Please enter your password.{Environment.NewLine}(Your password must contain at least 1 small-case letter,{Environment.NewLine}1 Capital letter, 1 digit, 1 special character{Environment.NewLine} and the length should be between 6-10 characters): ");
32 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.PasswordCompare] = GetInputFromUser(FieldConstants.UserRegistrationField.PasswordCompare, "Please re-enter your password: ");
33 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.DateOfBirth] = GetInputFromUser(FieldConstants.UserRegistrationField.DateOfBirth, "Please enter your date of birth: ");
34 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.PhoneNumber] = GetInputFromUser(FieldConstants.UserRegistrationField.PhoneNumber, "Please enter your phone number: ");
35 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.AddressFirstLine] = GetInputFromUser(FieldConstants.UserRegistrationField.AddressFirstLine, "Please enter the first line of your address: ");
36 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.AddressSecondLine] = GetInputFromUser(FieldConstants.UserRegistrationField.AddressSecondLine, "Please enter the second line of your address: ");
37 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.AddressCity] = GetInputFromUser(FieldConstants.UserRegistrationField.AddressCity, "Please enter the city where you live: ");
38 | _fieldValidator.FieldArray[(int)FieldConstants.UserRegistrationField.PostCode] = GetInputFromUser(FieldConstants.UserRegistrationField.PostCode, "Please enter your post code: ");
39 |
40 | RegisterUser();
41 | }
42 |
43 | private void RegisterUser()
44 | {
45 | _register.Register(_fieldValidator.FieldArray);
46 |
47 | CommonOutputFormat.ChangeFontColor(FontTheme.Success);
48 | Console.WriteLine("You have successfully registered. Please press any key to login");
49 | CommonOutputFormat.ChangeFontColor(FontTheme.Default);
50 | Console.ReadKey();
51 | }
52 |
53 | private string GetInputFromUser(FieldConstants.UserRegistrationField field, string promptText)
54 | {
55 | string fieldVal = "";
56 |
57 | do
58 | {
59 | Console.Write(promptText);
60 | fieldVal = Console.ReadLine();
61 | }
62 | while (!FieldValid(field, fieldVal));
63 |
64 | return fieldVal;
65 | }
66 |
67 | private bool FieldValid(FieldConstants.UserRegistrationField field, string fieldValue)
68 | {
69 | if (!_fieldValidator.ValidatorDel((int)field, fieldValue, _fieldValidator.FieldArray, out string invalidMessage))
70 | {
71 | CommonOutputFormat.ChangeFontColor(FontTheme.Danger);
72 |
73 | Console.WriteLine(invalidMessage);
74 |
75 | CommonOutputFormat.ChangeFontColor(FontTheme.Default);
76 |
77 | return false;
78 | }
79 | return true;
80 | }
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/ClubMembershipApplication/Views/WelcomeUserView.cs:
--------------------------------------------------------------------------------
1 | using ClubMembershipApplication.FieldValidators;
2 | using ClubMembershipApplication.Models;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace ClubMembershipApplication.Views
8 | {
9 |
10 |
11 | public class WelcomeUserView:IView
12 | {
13 | User _user = null;
14 |
15 | public WelcomeUserView(User user)
16 | {
17 | _user = user;
18 | }
19 |
20 | public IFieldValidator FieldValidator => null;
21 |
22 | public void RunView()
23 | {
24 | Console.Clear();
25 | CommonOutputText.WriteMainHeading();
26 |
27 | CommonOutputFormat.ChangeFontColor(FontTheme.Success);
28 | Console.WriteLine($"Hi {_user.FirstName}!!{Environment.NewLine}Welcome to the Cycling Club!!");
29 | CommonOutputFormat.ChangeFontColor(FontTheme.Default);
30 | Console.ReadKey();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/FieldValidatorAPI/CommonFieldValidatorFunctions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Text.RegularExpressions;
5 |
6 | namespace FieldValidatorAPI
7 | {
8 | public delegate bool RequiredValidDel(string fieldVal);
9 | public delegate bool StringLengthValidDel(string fieldVal, int min, int max);
10 | public delegate bool DateValidDel(string fieldVal, out DateTime validDateTime);
11 | public delegate bool PatternMatchValidDel(string fieldVal, string pattern);
12 | public delegate bool CompareFieldsValidDel(string fieldVal, string fieldValCompare);
13 | public class CommonFieldValidatorFunctions
14 | {
15 | private static RequiredValidDel _requiredValidDel = null;
16 | private static StringLengthValidDel _stringLengthValidDel = null;
17 | private static DateValidDel _dateValidDel = null;
18 | private static PatternMatchValidDel _patternMatchValidDel = null;
19 | private static CompareFieldsValidDel _compareFieldsValidDel = null;
20 |
21 | public static RequiredValidDel RequiredFieldValidDel
22 | {
23 | get
24 | {
25 | if (_requiredValidDel == null)
26 | _requiredValidDel = new RequiredValidDel(RequiredFieldValid);
27 |
28 | return _requiredValidDel;
29 | }
30 | }
31 |
32 | public static StringLengthValidDel StringLengthFieldValidDel
33 | {
34 | get
35 | {
36 | if (_stringLengthValidDel == null)
37 | _stringLengthValidDel = new StringLengthValidDel(StringFieldLengthValid);
38 |
39 | return _stringLengthValidDel;
40 | }
41 | }
42 | public static DateValidDel DateFieldValidDel
43 | {
44 | get
45 | {
46 | if (_dateValidDel == null)
47 | _dateValidDel = new DateValidDel(DateFieldValid);
48 |
49 | return _dateValidDel;
50 | }
51 | }
52 | public static PatternMatchValidDel PatternMatchValidDel
53 | {
54 | get
55 | {
56 | if (_patternMatchValidDel == null)
57 | _patternMatchValidDel = new PatternMatchValidDel(FieldPatternValid);
58 |
59 | return _patternMatchValidDel;
60 | }
61 | }
62 |
63 | public static CompareFieldsValidDel FieldsCompareValidDel
64 | {
65 | get
66 | {
67 | if (_compareFieldsValidDel == null)
68 | _compareFieldsValidDel = new CompareFieldsValidDel(FieldComparisonValid);
69 |
70 | return _compareFieldsValidDel;
71 | }
72 | }
73 |
74 |
75 | private static bool RequiredFieldValid(string fieldVal)
76 | {
77 | if (!string.IsNullOrEmpty(fieldVal))
78 | return true;
79 |
80 | return false;
81 |
82 | }
83 |
84 | private static bool StringFieldLengthValid(string fieldVal, int min, int max)
85 | {
86 | if (fieldVal.Length >= min && fieldVal.Length <= max)
87 | return true;
88 |
89 | return false;
90 |
91 | }
92 |
93 | private static bool DateFieldValid(string dateTime, out DateTime validDateTime)
94 | {
95 | if (DateTime.TryParse(dateTime, out validDateTime))
96 | return true;
97 |
98 | return false;
99 |
100 | }
101 |
102 | private static bool FieldPatternValid(string fieldVal, string regularExpressionPattern)
103 | {
104 | Regex regex = new Regex(regularExpressionPattern);
105 |
106 | if (regex.IsMatch(fieldVal))
107 | return true;
108 |
109 | return false;
110 |
111 | }
112 |
113 | private static bool FieldComparisonValid(string field1, string field2)
114 | {
115 | if (field1.Equals(field2))
116 | return true;
117 |
118 | return false;
119 | }
120 |
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/FieldValidatorAPI/CommonRegularExpressionValidationPatterns.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FieldValidatorAPI
6 | {
7 | public static class CommonRegularExpressionValidationPatterns
8 | {
9 |
10 | public const string Email_Address_RegEx_Pattern = @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$";
11 |
12 | public const string Uk_PhoneNumber_RegEx_Pattern = @"^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{5}\)?[\s-]?\d{4,5}|8(?:00[\s-]?11[\s-]?11|45[\s-]?46[\s-]?4\d))(?:(?:[\s-]?(?:x|ext\.?\s?|\#)\d+)?)$";
13 |
14 | public const string Uk_Post_Code_RegEx_Pattern = @"([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\s?[0-9][A-Za-z]{2})";
15 |
16 | public const string Strong_Password_RegEx_Pattern = @"(?=^.{6,10}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{":;'?/>.<,])(?!.*\s).*$";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/FieldValidatorAPI/FieldValidatorAPI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ClubMembershipApplication
2 | This code example is part of a tutorial on CSharp Delegates
3 | Please find the relevant tutorial at this location, https://www.youtube.com/watch?v=jABhPwEfA-I&lc=UgwmqSpc8z0An7NSWVl4AaABAg
4 | If you download this project and run it you'll get an exception (this is because you'll need to run relevant EF Core migration commands to build a SQLite database)
5 | Once you have run the relvant migration commands, the code will run as expected
6 | Please go through the video tutorial first before running the code
7 | I explain how to run the relevant EF Core migration commands at around the 13:54 mark.
8 |
--------------------------------------------------------------------------------